Back to index

plt-scheme  4.2.1
plvpor.c
Go to the documentation of this file.
00001 /* $Id: plvpor.c,v 1.2 2005/03/17 21:39:22 eli Exp $
00002 
00003        Functions dealing with viewports.
00004 */
00005 
00006 #include "plplotP.h"
00007 
00008 static void
00009 c_plenvi(PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
00010         PLINT just, PLINT axis, PLINT old);
00011 
00012 /*--------------------------------------------------------------------------*\
00013  * void plenv()
00014  *
00015  * Simple interface for defining viewport and window. 
00016  *
00017  * The "just" parameter control how the axes will be scaled:
00018  *
00019  *       just=-1 : The scales will not be set, the user must set up the scale
00020  *                   before calling plenv() using plsvpa(), plvasp() or other;
00021  *       just= 0 : The scales will be set up to optimize plot area;
00022  *       just= 1 : The scales will be the same; 
00023  *       just= 2 : The axes will be equal, the plot box will be square.
00024  * 
00025  * The "axis" parameter is interpreted as follows:
00026  *
00027  *     axis=-2 : draw no box, no tick marks, no numeric tick labels, no axes.
00028  *     axis=-1 : draw box only.
00029  *     axis= 0 : Draw box, ticks, and numeric tick labels.
00030  *     axis= 1 : Also draw coordinate axes at X=0, and Y=0.
00031  *     axis= 2 : Also draw a grid at major tick positions in both coordinates.
00032  *     axis= 3 : Same as 2, but the grid will be also at the minor ticks.
00033  *     axis=10 : Same as 0 except Logarithmic X tick marks. (The X data have
00034  *      to be converted to logarithms separately.)
00035  *     axis=11 : Same as 1 except Logarithmic X tick marks. (The X data have
00036  *      to be converted to logarithms separately.)
00037  *     axis=12 : Same as 2 except Logarithmic X tick marks. (The X data have
00038  *      to be converted to logarithms separately.)
00039  *      axis=13 : Same as 12, but the grid will be also at the minor ticks.
00040  *     axis=20 : Same as 0 except Logarithmic Y tick marks. (The Y data have
00041  *      to be converted to logarithms separately.)
00042  *     axis=21 : Same as 1 except Logarithmic Y tick marks. (The Y data have
00043  *      to be converted to logarithms separately.)
00044  *     axis=22 : Same as 2 except Logarithmic Y tick marks. (The Y data have
00045  *      to be converted to logarithms separately.)
00046  *      axis=23 : Same as 22, but the grid will be also at the minor ticks.
00047  *     axis=30 : Same as 0 except Logarithmic X,Y tick marks. (The X,Y data have
00048  *      to be converted to logarithms separately.)
00049  *     axis=31 : Same as 1 except Logarithmic X,Y tick marks. (The X,Y data have
00050  *      to be converted to logarithms separately.)
00051  *     axis=32 : Same as 2 except Logarithmic X,Y tick marks. (The X,Y data have
00052  *      to be converted to logarithms separately.)
00053  *      axis=33 : Same as 32, but the grid will be also at the minor ticks.
00054 \*--------------------------------------------------------------------------*/
00055 
00056 MZ_DLLEXPORT
00057 void
00058 c_plenv(PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
00059        PLINT just, PLINT axis)
00060 {
00061   c_plenvi(xmin, xmax, ymin, ymax, just, axis, 1); 
00062 }
00063 
00064 /*--------------------------------------------------------------------------*\
00065  * void plenv0()
00066  *
00067  * same as plenv() above, but if in multiplot mode does not advance the subpage,
00068  * instead clears it.
00069 \*--------------------------------------------------------------------------*/
00070 
00071 void
00072 c_plenv0(PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
00073        PLINT just, PLINT axis)
00074 {
00075   c_plenvi(xmin, xmax, ymin, ymax, just, axis, 0); 
00076 }
00077 
00078 
00079 static void
00080 c_plenvi(PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
00081        PLINT just, PLINT axis, PLINT old)
00082 {
00083     PLFLT lb, rb, tb, bb, dx, dy;
00084     PLFLT xsize, ysize, size, xscale, yscale, scale;
00085     PLFLT spxmin, spxmax, spymin, spymax;
00086     PLFLT vpxmin, vpxmax, vpymin, vpymax;
00087 
00088     if (plsc->level < 1) {
00089        plabort("plenv: Please call plinit first");
00090        return;
00091     }
00092     if (xmin == xmax) {
00093        plabort("plenv: Invalid xmin and xmax arguments");
00094        return;
00095     }
00096     if (ymin == ymax) {
00097        plabort("plenv: Invalid ymin and ymax arguments");
00098        return;
00099     }
00100     if (just < -1 || just > 2) {
00101        plabort("plenv: Invalid just option");
00102        return;
00103     }
00104 
00105     if (plsc->nsubx * plsc->nsuby == 1) /* not multiplot mode */
00106       old = 1;
00107 
00108     if (old == 1)
00109       pladv(0);
00110     else 
00111       plclear();
00112 
00113     if (just == 0)
00114        plvsta();
00115     else  if (just == 1){
00116        lb = 8.0 * plsc->chrht;
00117        rb = 5.0 * plsc->chrht;
00118        tb = 5.0 * plsc->chrht;
00119        bb = 5.0 * plsc->chrht;
00120        dx = ABS(xmax - xmin);
00121        dy = ABS(ymax - ymin);
00122        plgspa(&spxmin, &spxmax, &spymin, &spymax);
00123        xsize = spxmax - spxmin;
00124        ysize = spymax - spymin;
00125        xscale = dx / (xsize - lb - rb);
00126        yscale = dy / (ysize - tb - bb);
00127        scale = MAX(xscale, yscale);
00128        vpxmin = MAX(lb, 0.5 * (xsize - dx / scale));
00129        vpxmax = vpxmin + (dx / scale);
00130        vpymin = MAX(bb, 0.5 * (ysize - dy / scale));
00131        vpymax = vpymin + (dy / scale);
00132        plsvpa(vpxmin, vpxmax, vpymin, vpymax);
00133     } else if(just == 2) {
00134         lb = 8.0 * plsc->chrht;
00135         rb = 5.0 * plsc->chrht;
00136        tb = 5.0 * plsc->chrht;
00137        bb = 5.0 * plsc->chrht;
00138        plgspa(&spxmin, &spxmax, &spymin, &spymax);
00139        xsize = spxmax - spxmin;
00140        ysize = spymax - spymin;
00141        size = MIN(xsize-lb-rb, ysize-tb-bb);
00142        dx = (xsize-size-lb-rb)/2;
00143        vpxmin = lb + dx;
00144        vpxmax = vpxmin + size;
00145        dy = (ysize-size-bb-tb)/2;
00146        vpymin = bb + dy;
00147        vpymax = vpymin + size;
00148        plsvpa(vpxmin, vpxmax, vpymin, vpymax);
00149     }
00150 
00151     plwind(xmin, xmax, ymin, ymax);
00152 
00153     switch (axis) {
00154     case -2:
00155        break;
00156     case -1:
00157        plbox("bc", (PLFLT) 0.0, 0, "bc", (PLFLT) 0.0, 0);
00158        break;
00159     case 0:
00160        plbox("bcnst", (PLFLT) 0.0, 0, "bcnstv", (PLFLT) 0.0, 0);
00161        break;
00162     case 1:
00163        plbox("abcnst", (PLFLT) 0.0, 0, "abcnstv", (PLFLT) 0.0, 0);
00164        break;
00165     case 2:
00166        plbox("abcgnst", (PLFLT) 0.0, 0, "abcgnstv", (PLFLT) 0.0, 0);
00167        break;
00168     case 3:
00169        plbox("abcgnsth", (PLFLT) 0.0, 0, "abcgnstvh", (PLFLT) 0.0, 0);
00170        break;
00171     case 10:
00172        plbox("bclnst", (PLFLT) 0.0, 0, "bcnstv", (PLFLT) 0.0, 0);
00173        break;
00174     case 11:
00175        plbox("abclnst", (PLFLT) 0.0, 0, "abcnstv", (PLFLT) 0.0, 0);
00176        break;
00177     case 12:
00178        plbox("abcglnst", (PLFLT) 0.0, 0, "abcgnstv", (PLFLT) 0.0, 0);
00179        break;
00180     case 13:
00181        plbox("abcglnsth", (PLFLT) 0.0, 0, "abcgnstvh", (PLFLT) 0.0, 0);
00182        break;
00183     case 20:
00184        plbox("bcnst", (PLFLT) 0.0, 0, "bclnstv", (PLFLT) 0.0, 0);
00185        break;
00186     case 21:
00187        plbox("abcnst", (PLFLT) 0.0, 0, "abclnstv", (PLFLT) 0.0, 0);
00188        break;
00189     case 22:
00190        plbox("abcgnst", (PLFLT) 0.0, 0, "abcglnstv", (PLFLT) 0.0, 0);
00191        break; 
00192     case 23:
00193        plbox("abcgnsth", (PLFLT) 0.0, 0, "abcglnstvh", (PLFLT) 0.0, 0);
00194        break; 
00195     case 30:
00196        plbox("bclnst", (PLFLT) 0.0, 0, "bclnstv", (PLFLT) 0.0, 0);
00197        break;
00198     case 31:
00199        plbox("abclnst", (PLFLT) 0.0, 0, "abclnstv", (PLFLT) 0.0, 0);
00200        break;
00201     case 32:
00202        plbox("abcglnst", (PLFLT) 0.0, 0, "abcglnstv", (PLFLT) 0.0, 0);
00203        break; 
00204     case 33:
00205        plbox("abcglnsth", (PLFLT) 0.0, 0, "abcglnstvh", (PLFLT) 0.0, 0);
00206        break; 
00207     default:
00208        plwarn("plenv: Invalid axis argument");
00209     }
00210 }
00211 
00212 /*--------------------------------------------------------------------------*\
00213  * void plvsta()
00214  *
00215  * Defines a "standard" viewport with seven character heights for
00216  * the left margin and four character heights everywhere else.
00217 \*--------------------------------------------------------------------------*/
00218 
00219 void
00220 c_plvsta(void)
00221 {
00222     PLFLT xmin, xmax, ymin, ymax;
00223     PLFLT lb, rb, tb, bb;
00224 
00225     if (plsc->level < 1) {
00226        plabort("plvsta: Please call plinit first");
00227        return;
00228     }
00229 
00230 /*  Find out position of subpage boundaries in millimetres, reduce by */
00231 /*  the desired border, and convert back into normalized subpage */
00232 /*  coordinates */
00233 
00234     lb = 8.0 * plsc->chrht;
00235     rb = 5.0 * plsc->chrht;
00236     tb = 5.0 * plsc->chrht;
00237     bb = 5.0 * plsc->chrht;
00238 
00239     xmin = plP_dcscx(plP_mmdcx((PLFLT) (plP_dcmmx(plsc->spdxmi) + lb)));
00240     xmax = plP_dcscx(plP_mmdcx((PLFLT) (plP_dcmmx(plsc->spdxma) - rb)));
00241     ymin = plP_dcscy(plP_mmdcy((PLFLT) (plP_dcmmy(plsc->spdymi) + tb)));
00242     ymax = plP_dcscy(plP_mmdcy((PLFLT) (plP_dcmmy(plsc->spdyma) - bb)));
00243 
00244     plvpor(xmin, xmax, ymin, ymax);
00245 }
00246 
00247 /*--------------------------------------------------------------------------*\
00248  * void plvpor()
00249  *
00250  * Creates a viewport with the specified normalized subpage coordinates.
00251 \*--------------------------------------------------------------------------*/
00252 
00253 void
00254 c_plvpor(PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax)
00255 {
00256     if (plsc->level < 1) {
00257        plabort("plvpor: Please call plinit first");
00258        return;
00259     }
00260     if ((xmin >= xmax) || (ymin >= ymax)) {
00261        plabort("plvpor: Invalid limits");
00262        return;
00263     }
00264     if ((plsc->cursub <= 0) || (plsc->cursub > (plsc->nsubx * plsc->nsuby))) {
00265        plabort("plvpor: Please call pladv or plenv to go to a subpage");
00266        return;
00267     }
00268 
00269     plsc->vpdxmi = plsc->spdxmi + (plsc->spdxma - plsc->spdxmi) * xmin;
00270     plsc->vpdxma = plsc->spdxmi + (plsc->spdxma - plsc->spdxmi) * xmax;
00271     plsc->vpdymi = plsc->spdymi + (plsc->spdyma - plsc->spdymi) * ymin;
00272     plsc->vpdyma = plsc->spdymi + (plsc->spdyma - plsc->spdymi) * ymax;
00273 
00274     plsc->vppxmi = plP_dcpcx(plsc->vpdxmi);
00275     plsc->vppxma = plP_dcpcx(plsc->vpdxma);
00276     plsc->vppymi = plP_dcpcy(plsc->vpdymi);
00277     plsc->vppyma = plP_dcpcy(plsc->vpdyma);
00278 
00279     plsc->clpxmi = MAX(plsc->vppxmi, plsc->phyxmi);
00280     plsc->clpxma = MIN(plsc->vppxma, plsc->phyxma);
00281     plsc->clpymi = MAX(plsc->vppymi, plsc->phyymi);
00282     plsc->clpyma = MIN(plsc->vppyma, plsc->phyyma);
00283 
00284     plsc->level = 2;
00285 }
00286 
00287 /*--------------------------------------------------------------------------*\
00288  * void plvpas()
00289  *
00290  * Creates the largest viewport of the specified aspect ratio that fits
00291  * within the specified normalized subpage coordinates.
00292 \*--------------------------------------------------------------------------*/
00293 
00294 void
00295 c_plvpas(PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT aspect)
00296 {
00297     PLFLT vpxmi, vpxma, vpymi, vpyma;
00298     PLFLT vpxmid, vpymid, vpxlen, vpylen, w_aspect, ratio;
00299 
00300     if (plsc->level < 1) {
00301        plabort("plvpas: Please call plinit first");
00302        return;
00303     }
00304     if ((xmin >= xmax) || (ymin >= ymax)) {
00305        plabort("plvpas: Invalid limits");
00306        return;
00307     }
00308 
00309     if (aspect <= 0.0) {
00310        c_plvpor(xmin, xmax, ymin, ymax);
00311        return;
00312     }
00313 
00314     vpxmi = plP_dcmmx(xmin);
00315     vpxma = plP_dcmmx(xmax);
00316     vpymi = plP_dcmmy(ymin);
00317     vpyma = plP_dcmmy(ymax);
00318 
00319     vpxmid = (vpxmi + vpxma) / 2.;
00320     vpymid = (vpymi + vpyma) / 2.;
00321 
00322     vpxlen = vpxma - vpxmi;
00323     vpylen = vpyma - vpymi;
00324 
00325     w_aspect = vpylen / vpxlen;
00326     ratio = aspect / w_aspect;
00327 
00328 /*
00329  * If ratio < 1, you are requesting an aspect ratio (y/x) less than the natural
00330  * aspect ratio of the specified window, and you will need to reduce the length
00331  * in y correspondingly.  Similarly, for ratio > 1, x length must be reduced.
00332  */
00333 
00334     if (ratio <= 0.) {
00335        plabort("plvpas: Error in aspect ratio setting");
00336        return;
00337     }
00338     else if (ratio < 1.)
00339        vpylen = vpylen * ratio;
00340     else
00341        vpxlen = vpxlen / ratio;
00342 
00343     vpxmi = vpxmid - vpxlen / 2.;
00344     vpxma = vpxmid + vpxlen / 2.;
00345     vpymi = vpymid - vpylen / 2.;
00346     vpyma = vpymid + vpylen / 2.;
00347 
00348     plsvpa(vpxmi, vpxma, vpymi, vpyma);
00349 }
00350 
00351 /*--------------------------------------------------------------------------*\
00352  * void plvasp()
00353  *
00354  * Sets the edges of the viewport with the given aspect ratio, leaving
00355  * room for labels.
00356 \*--------------------------------------------------------------------------*/
00357 
00358 void
00359 c_plvasp(PLFLT aspect)
00360 {
00361     PLFLT spxmin, spxmax, spymin, spymax;
00362     PLFLT vpxmin, vpxmax, vpymin, vpymax;
00363     PLFLT xsize, ysize, nxsize, nysize;
00364     PLFLT lb, rb, tb, bb;
00365 
00366     if (plsc->level < 1) {
00367        plabort("plvasp: Please call plinit first");
00368        return;
00369     }
00370 
00371     lb = 8.0 * plsc->chrht;
00372     rb = 5.0 * plsc->chrht;
00373     tb = 5.0 * plsc->chrht;
00374     bb = 5.0 * plsc->chrht;
00375 
00376     plgspa(&spxmin, &spxmax, &spymin, &spymax);
00377     xsize = spxmax - spxmin;
00378     ysize = spymax - spymin;
00379     xsize -= lb + rb;              /* adjust for labels */
00380     ysize -= bb + tb;
00381     if (aspect * xsize > ysize) {
00382        nxsize = ysize / aspect;
00383        nysize = ysize;
00384     }
00385     else {
00386        nxsize = xsize;
00387        nysize = xsize * aspect;
00388     }
00389 
00390 /* center plot within page */
00391 
00392     vpxmin = .5 * (xsize - nxsize) + lb;
00393     vpxmax = vpxmin + nxsize;
00394     vpymin = .5 * (ysize - nysize) + bb;
00395     vpymax = vpymin + nysize;
00396 
00397     plsvpa(vpxmin, vpxmax, vpymin, vpymax);
00398 }
00399 
00400 /*--------------------------------------------------------------------------*\
00401  * void plsvpa()
00402  *
00403  * Sets the edges of the viewport to the specified absolute coordinates
00404  * (mm), measured with respect to the current subpage boundaries.
00405 \*--------------------------------------------------------------------------*/
00406 
00407 void
00408 c_plsvpa(PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax)
00409 {
00410     PLFLT sxmin, symin;
00411 
00412     if (plsc->level < 1) {
00413        plabort("plsvpa: Please call plinit first");
00414        return;
00415     }
00416     if ((xmin >= xmax) || (ymin >= ymax)) {
00417        plabort("plsvpa: Invalid limits");
00418        return;
00419     }
00420     if ((plsc->cursub <= 0) || (plsc->cursub > (plsc->nsubx * plsc->nsuby))) {
00421        plabort("plsvpa: Please call pladv or plenv to go to a subpage");
00422        return;
00423     }
00424 
00425     sxmin = plP_dcmmx(plsc->spdxmi);
00426     symin = plP_dcmmy(plsc->spdymi);
00427 
00428     plsc->vpdxmi = plP_mmdcx((PLFLT) (sxmin + xmin));
00429     plsc->vpdxma = plP_mmdcx((PLFLT) (sxmin + xmax));
00430     plsc->vpdymi = plP_mmdcy((PLFLT) (symin + ymin));
00431     plsc->vpdyma = plP_mmdcy((PLFLT) (symin + ymax));
00432 
00433     plsc->vppxmi = plP_dcpcx(plsc->vpdxmi);
00434     plsc->vppxma = plP_dcpcx(plsc->vpdxma);
00435     plsc->vppymi = plP_dcpcy(plsc->vpdymi);
00436     plsc->vppyma = plP_dcpcy(plsc->vpdyma);
00437 
00438     plsc->clpxmi = plP_dcpcx(plsc->vpdxmi);
00439     plsc->clpxma = plP_dcpcx(plsc->vpdxma);
00440     plsc->clpymi = plP_dcpcy(plsc->vpdymi);
00441     plsc->clpyma = plP_dcpcy(plsc->vpdyma);
00442 
00443     plsc->level = 2;
00444 }