home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / maths / plplot / plplot_2 / src / plvpor.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-30  |  10.5 KB  |  381 lines

  1. /* $Id: plvpor.c,v 1.9 1994/06/30 18:22:23 mjl Exp $
  2.  * $Log: plvpor.c,v $
  3.  * Revision 1.9  1994/06/30  18:22:23  mjl
  4.  * All core source files: made another pass to eliminate warnings when using
  5.  * gcc -Wall.  Lots of cleaning up: got rid of includes of math.h or string.h
  6.  * (now included by plplot.h), and other minor changes.  Now each file has
  7.  * global access to the plstream pointer via extern; many accessor functions
  8.  * eliminated as a result.
  9.  *
  10.  * Revision 1.8  1994/03/23  08:35:28  mjl
  11.  * All external API source files: replaced call to plexit() on simple
  12.  * (recoverable) errors with simply printing the error message (via
  13.  * plabort()) and returning.  Should help avoid loss of computer time in some
  14.  * critical circumstances (during a long batch run, for example).
  15. */
  16.  
  17. /*    plvpor.c
  18.  
  19.     Functions dealing with viewports.
  20. */
  21.  
  22. #include "plplotP.h"
  23.  
  24. /*----------------------------------------------------------------------*\
  25.  * void plenv()
  26.  *
  27.  * Simple interface for defining viewport and window. If "just"=1,
  28.  * X and Y scales will be the same, otherwise they are scaled
  29.  * independently. The "axis" parameter is interpreted as follows:
  30.  *
  31.  *    axis=-2 : draw no box, axis or labels
  32.  *    axis=-1 : draw box only
  33.  *    axis= 0 : Draw box and label with coordinates
  34.  *    axis= 1 : Also draw the coordinate axes
  35.  *    axis= 2 : Draw a grid at major tick positions
  36.  *    axis=10 : Logarithmic X axis, Linear Y axis, No X=0 axis
  37.  *    axis=11 : Logarithmic X axis, Linear Y axis, X=0 axis
  38.  *    axis=20 : Linear X axis, Logarithmic Y axis, No Y=0 axis
  39.  *    axis=21 : Linear X axis, Logarithmic Y axis, Y=0 axis
  40.  *    axis=30 : Logarithmic X and Y axes
  41. \*----------------------------------------------------------------------*/
  42.  
  43. void
  44. c_plenv(PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
  45.     PLINT just, PLINT axis)
  46. {
  47.     PLFLT lb, rb, tb, bb, dx, dy;
  48.     PLFLT xsize, ysize, xscale, yscale, scale;
  49.     PLFLT spxmin, spxmax, spymin, spymax;
  50.     PLFLT vpxmin, vpxmax, vpymin, vpymax;
  51.  
  52.     if (plsc->level < 1) {
  53.     plabort("plenv: Please call plinit first");
  54.     return;
  55.     }
  56.     if (xmin == xmax) {
  57.     plabort("plenv: Invalid xmin and xmax arguments");
  58.     return;
  59.     }
  60.     if (ymin == ymax) {
  61.     plabort("plenv: Invalid ymin and ymax arguments");
  62.     return;
  63.     }
  64.     if ((just != 0) && (just != 1)) {
  65.     plabort("plenv: Invalid just option");
  66.     return;
  67.     }
  68.  
  69.     pladv(0);
  70.  
  71.     if (just == 0)
  72.     plvsta();
  73.     else {
  74.     lb = 8.0 * plsc->chrht;
  75.     rb = 5.0 * plsc->chrht;
  76.     tb = 5.0 * plsc->chrht;
  77.     bb = 5.0 * plsc->chrht;
  78.     dx = ABS(xmax - xmin);
  79.     dy = ABS(ymax - ymin);
  80.     plgspa(&spxmin, &spxmax, &spymin, &spymax);
  81.     xsize = spxmax - spxmin;
  82.     ysize = spymax - spymin;
  83.     xscale = dx / (xsize - lb - rb);
  84.     yscale = dy / (ysize - tb - bb);
  85.     scale = MAX(xscale, yscale);
  86.     vpxmin = MAX(lb, 0.5 * (xsize - dx / scale));
  87.     vpxmax = vpxmin + (dx / scale);
  88.     vpymin = MAX(bb, 0.5 * (ysize - dy / scale));
  89.     vpymax = vpymin + (dy / scale);
  90.  
  91.     plsvpa(vpxmin, vpxmax, vpymin, vpymax);
  92.     }
  93.  
  94.     plwind(xmin, xmax, ymin, ymax);
  95.  
  96.     switch (axis) {
  97.     case -2:
  98.     break;
  99.     case -1:
  100.     plbox("bc", (PLFLT) 0.0, 0, "bc", (PLFLT) 0.0, 0);
  101.     break;
  102.     case 0:
  103.     plbox("bcnst", (PLFLT) 0.0, 0, "bcnstv", (PLFLT) 0.0, 0);
  104.     break;
  105.     case 1:
  106.     plbox("abcnst", (PLFLT) 0.0, 0, "abcnstv", (PLFLT) 0.0, 0);
  107.     break;
  108.     case 2:
  109.     plbox("abcgnst", (PLFLT) 0.0, 0, "abcgnstv", (PLFLT) 0.0, 0);
  110.     break;
  111.     case 10:
  112.     plbox("bclnst", (PLFLT) 0.0, 0, "bcnstv", (PLFLT) 0.0, 0);
  113.     break;
  114.     case 11:
  115.     plbox("bclnst", (PLFLT) 0.0, 0, "abcnstv", (PLFLT) 0.0, 0);
  116.     break;
  117.     case 20:
  118.     plbox("bcnst", (PLFLT) 0.0, 0, "bclnstv", (PLFLT) 0.0, 0);
  119.     break;
  120.     case 21:
  121.     plbox("bcnst", (PLFLT) 0.0, 0, "abclnstv", (PLFLT) 0.0, 0);
  122.     break;
  123.     case 30:
  124.     plbox("bclnst", (PLFLT) 0.0, 0, "bclnstv", (PLFLT) 0.0, 0);
  125.     break;
  126.     default:
  127.     plwarn("plenv: Invalid axis argument");
  128.     }
  129. }
  130.  
  131. /*----------------------------------------------------------------------*\
  132.  * void plvsta()
  133.  *
  134.  * Defines a "standard" viewport with seven character heights for
  135.  * the left margin and four character heights everywhere else.
  136. \*----------------------------------------------------------------------*/
  137.  
  138. void
  139. c_plvsta(void)
  140. {
  141.     PLFLT xmin, xmax, ymin, ymax;
  142.     PLFLT spdxmi, spdxma, spdymi, spdyma;
  143.     PLFLT lb, rb, tb, bb;
  144.  
  145.     if (plsc->level < 1) {
  146.     plabort("plvsta: Please call plinit first");
  147.     return;
  148.     }
  149.  
  150.     plP_gspd(&spdxmi, &spdxma, &spdymi, &spdyma);
  151.  
  152. /*  Find out position of subpage boundaries in millimetres, reduce by */
  153. /*  the desired border, and convert back into normalized subpage */
  154. /*  coordinates */
  155.  
  156.     lb = 8.0 * plsc->chrht;
  157.     rb = 5.0 * plsc->chrht;
  158.     tb = 5.0 * plsc->chrht;
  159.     bb = 5.0 * plsc->chrht;
  160.  
  161.     xmin = plP_dcscx(plP_mmdcx((PLFLT) (plP_dcmmx(spdxmi) + lb)));
  162.     xmax = plP_dcscx(plP_mmdcx((PLFLT) (plP_dcmmx(spdxma) - rb)));
  163.     ymin = plP_dcscy(plP_mmdcy((PLFLT) (plP_dcmmy(spdymi) + tb)));
  164.     ymax = plP_dcscy(plP_mmdcy((PLFLT) (plP_dcmmy(spdyma) - bb)));
  165.  
  166.     plvpor(xmin, xmax, ymin, ymax);
  167. }
  168.  
  169. /*----------------------------------------------------------------------*\
  170.  * void plvpor()
  171.  *
  172.  * Creates a viewport with the specified normalized subpage coordinates.
  173. \*----------------------------------------------------------------------*/
  174.  
  175. void
  176. c_plvpor(PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax)
  177. {
  178.     PLFLT spdxmi, spdxma, spdymi, spdyma;
  179.     PLFLT vpdxmi, vpdxma, vpdymi, vpdyma;
  180.     PLINT vppxmi, vppxma, vppymi, vppyma;
  181.     PLINT clpxmi, clpxma, clpymi, clpyma;
  182.     PLINT phyxmi, phyxma, phyymi, phyyma;
  183.     PLINT nx, ny, cs;
  184.  
  185.     if (plsc->level < 1) {
  186.     plabort("plvpor: Please call plinit first");
  187.     return;
  188.     }
  189.     if ((xmin >= xmax) || (ymin >= ymax)) {
  190.     plabort("plvpor: Invalid limits");
  191.     return;
  192.     }
  193.     plP_gsub(&nx, &ny, &cs);
  194.     if ((cs <= 0) || (cs > (nx * ny))) {
  195.     plabort("plvpor: Please call pladv or plenv to go to a subpage");
  196.     return;
  197.     }
  198.  
  199.     plP_gspd(&spdxmi, &spdxma, &spdymi, &spdyma);
  200.     vpdxmi = spdxmi + (spdxma - spdxmi) * xmin;
  201.     vpdxma = spdxmi + (spdxma - spdxmi) * xmax;
  202.     vpdymi = spdymi + (spdyma - spdymi) * ymin;
  203.     vpdyma = spdymi + (spdyma - spdymi) * ymax;
  204.     plP_svpd(vpdxmi, vpdxma, vpdymi, vpdyma);
  205.  
  206.     vppxmi = plP_dcpcx(vpdxmi);
  207.     vppxma = plP_dcpcx(vpdxma);
  208.     vppymi = plP_dcpcy(vpdymi);
  209.     vppyma = plP_dcpcy(vpdyma);
  210.     plP_svpp(vppxmi, vppxma, vppymi, vppyma);
  211.  
  212.     plP_gphy(&phyxmi, &phyxma, &phyymi, &phyyma);
  213.     clpxmi = MAX(vppxmi, phyxmi);
  214.     clpxma = MIN(vppxma, phyxma);
  215.     clpymi = MAX(vppymi, phyymi);
  216.     clpyma = MIN(vppyma, phyyma);
  217.     plP_sclp(clpxmi, clpxma, clpymi, clpyma);
  218.  
  219.     plsc->level = 2;
  220. }
  221.  
  222. /*----------------------------------------------------------------------*\
  223.  * void plvpas()
  224.  *
  225.  * Creates the largest viewport of the specified aspect ratio that fits
  226.  * within the specified normalized subpage coordinates.
  227. \*----------------------------------------------------------------------*/
  228.  
  229. void
  230. c_plvpas(PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT aspect)
  231. {
  232.     PLFLT vpxmi, vpxma, vpymi, vpyma;
  233.     PLFLT vpxmid, vpymid, vpxlen, vpylen, w_aspect, ratio;
  234.  
  235.     if (plsc->level < 1) {
  236.     plabort("plvpas: Please call plinit first");
  237.     return;
  238.     }
  239.     if ((xmin >= xmax) || (ymin >= ymax)) {
  240.     plabort("plvpas: Invalid limits");
  241.     return;
  242.     }
  243.  
  244.     if (aspect <= 0.0) {
  245.     c_plvpor(xmin, xmax, ymin, ymax);
  246.     return;
  247.     }
  248.  
  249.     vpxmi = plP_dcmmx(xmin);
  250.     vpxma = plP_dcmmx(xmax);
  251.     vpymi = plP_dcmmy(ymin);
  252.     vpyma = plP_dcmmy(ymax);
  253.  
  254.     vpxmid = (vpxmi + vpxma) / 2.;
  255.     vpymid = (vpymi + vpyma) / 2.;
  256.  
  257.     vpxlen = vpxma - vpxmi;
  258.     vpylen = vpyma - vpymi;
  259.  
  260.     w_aspect = vpylen / vpxlen;
  261.     ratio = aspect / w_aspect;
  262.  
  263. /*
  264.  * If ratio < 1, you are requesting an aspect ratio (y/x) less than the natural
  265.  * aspect ratio of the specified window, and you will need to reduce the length
  266.  * in y correspondingly.  Similarly, for ratio > 1, x length must be reduced.
  267.  */
  268.  
  269.     if (ratio <= 0.) {
  270.     plabort("plvpas: Error in aspect ratio setting");
  271.     return;
  272.     }
  273.     else if (ratio < 1.)
  274.     vpylen = vpylen * ratio;
  275.     else
  276.     vpxlen = vpxlen / ratio;
  277.  
  278.     vpxmi = vpxmid - vpxlen / 2.;
  279.     vpxma = vpxmid + vpxlen / 2.;
  280.     vpymi = vpymid - vpylen / 2.;
  281.     vpyma = vpymid + vpylen / 2.;
  282.  
  283.     plsvpa(vpxmi, vpxma, vpymi, vpyma);
  284. }
  285.  
  286. /*----------------------------------------------------------------------*\
  287.  * void plvasp()
  288.  *
  289.  * Sets the edges of the viewport with the given aspect ratio, leaving
  290.  * room for labels.
  291. \*----------------------------------------------------------------------*/
  292.  
  293. void
  294. c_plvasp(PLFLT aspect)
  295. {
  296.     PLFLT spxmin, spxmax, spymin, spymax;
  297.     PLFLT vpxmin, vpxmax, vpymin, vpymax;
  298.     PLFLT xsize, ysize, nxsize, nysize;
  299.     PLFLT lb, rb, tb, bb;
  300.  
  301.     if (plsc->level < 1) {
  302.     plabort("plvasp: Please call plinit first");
  303.     return;
  304.     }
  305.  
  306.     lb = 8.0 * plsc->chrht;
  307.     rb = 5.0 * plsc->chrht;
  308.     tb = 5.0 * plsc->chrht;
  309.     bb = 5.0 * plsc->chrht;
  310.  
  311.     plgspa(&spxmin, &spxmax, &spymin, &spymax);
  312.     xsize = spxmax - spxmin;
  313.     ysize = spymax - spymin;
  314.     xsize -= lb + rb;        /* adjust for labels */
  315.     ysize -= bb + tb;
  316.     if (aspect * xsize > ysize) {
  317.     nxsize = ysize / aspect;
  318.     nysize = ysize;
  319.     }
  320.     else {
  321.     nxsize = xsize;
  322.     nysize = xsize * aspect;
  323.     }
  324.  
  325. /* center plot within page */
  326.  
  327.     vpxmin = .5 * (xsize - nxsize) + lb;
  328.     vpxmax = vpxmin + nxsize;
  329.     vpymin = .5 * (ysize - nysize) + bb;
  330.     vpymax = vpymin + nysize;
  331.  
  332.     plsvpa(vpxmin, vpxmax, vpymin, vpymax);
  333. }
  334.  
  335. /*----------------------------------------------------------------------*\
  336.  * void plsvpa()
  337.  *
  338.  * Sets the edges of the viewport to the specified absolute coordinates
  339.  * (mm), measured with respect to the current subpage boundaries.
  340. \*----------------------------------------------------------------------*/
  341.  
  342. void
  343. c_plsvpa(PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax)
  344. {
  345.     PLINT nx, ny, cs;
  346.     PLFLT sxmin, symin;
  347.     PLFLT spdxmi, spdxma, spdymi, spdyma;
  348.     PLFLT vpdxmi, vpdxma, vpdymi, vpdyma;
  349.  
  350.     if (plsc->level < 1) {
  351.     plabort("plsvpa: Please call plinit first");
  352.     return;
  353.     }
  354.     if ((xmin >= xmax) || (ymin >= ymax)) {
  355.     plabort("plsvpa: Invalid limits");
  356.     return;
  357.     }
  358.     plP_gsub(&nx, &ny, &cs);
  359.     if ((cs <= 0) || (cs > (nx * ny))) {
  360.     plabort("plsvpa: Please call pladv or plenv to go to a subpage");
  361.     return;
  362.     }
  363.  
  364.     plP_gspd(&spdxmi, &spdxma, &spdymi, &spdyma);
  365.     sxmin = plP_dcmmx(spdxmi);
  366.     symin = plP_dcmmy(spdymi);
  367.  
  368.     vpdxmi = plP_mmdcx((PLFLT) (sxmin + xmin));
  369.     vpdxma = plP_mmdcx((PLFLT) (sxmin + xmax));
  370.     vpdymi = plP_mmdcy((PLFLT) (symin + ymin));
  371.     vpdyma = plP_mmdcy((PLFLT) (symin + ymax));
  372.  
  373.     plP_svpd(vpdxmi, vpdxma, vpdymi, vpdyma);
  374.     plP_svpp(plP_dcpcx(vpdxmi), plP_dcpcx(vpdxma),
  375.          plP_dcpcy(vpdymi), plP_dcpcy(vpdyma));
  376.     plP_sclp(plP_dcpcx(vpdxmi), plP_dcpcx(vpdxma),
  377.          plP_dcpcy(vpdymi), plP_dcpcy(vpdyma));
  378.  
  379.     plsc->level = 2;
  380. }
  381.