PLplot: plvpor.c Source File

PLplot 5.10.0

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
plvpor.c
Go to the documentation of this file.
1 // $Id: plvpor.c 11973 2011-10-17 21:16:39Z andrewross $
2 //
3 // Functions dealing with viewports.
4 //
5 // Copyright (C) 2004 Joao Cardoso
6 //
7 // This file is part of PLplot.
8 //
9 // PLplot is free software; you can redistribute it and/or modify
10 // it under the terms of the GNU Library General Public License as published
11 // by the Free Software Foundation; either version 2 of the License, or
12 // (at your option) any later version.
13 //
14 // PLplot is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU Library General Public License for more details.
18 //
19 // You should have received a copy of the GNU Library General Public License
20 // along with PLplot; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 //
23
24 #include "plplotP.h"
25
26 static void
27 c_plenvi( PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
28 PLINT just, PLINT axis, PLINT old );
29
30 //--------------------------------------------------------------------------
31 // void plenv()
32 //
33 // Simple interface for defining viewport and window.
34 //
35 // The "just" parameter control how the axes will be scaled:
36 //
37 // just=-1 : The scales will not be set, the user must set up the scale
38 // before calling plenv() using plsvpa(), plvasp() or other;
39 // just= 0 : The scales will be set up to optimize plot area;
40 // just= 1 : The scales will be the same;
41 // just= 2 : The axes will be equal, the plot box will be square.
42 //
43 // The "axis" parameter is interpreted as follows:
44 //
45 // axis=-2 : draw no box, no tick marks, no numeric tick labels, no axes.
46 // axis=-1 : draw box only.
47 // axis= 0 : Draw box, ticks, and numeric tick labels.
48 // axis= 1 : Also draw coordinate axes at X=0, and Y=0.
49 // axis= 2 : Also draw a grid at major tick positions in both coordinates.
50 // axis= 3 : Same as 2, but the grid will be also at the minor ticks.
51 // axis=10 : Same as 0 except Logarithmic X tick marks. (The X data have
52 // to be converted to logarithms separately.)
53 // axis=11 : Same as 1 except Logarithmic X tick marks. (The X data have
54 // to be converted to logarithms separately.)
55 // axis=12 : Same as 2 except Logarithmic X tick marks. (The X data have
56 // to be converted to logarithms separately.)
57 // axis=13 : Same as 12, but the grid will be also at the minor ticks.
58 // axis=20 : Same as 0 except Logarithmic Y tick marks. (The Y data have
59 // to be converted to logarithms separately.)
60 // axis=21 : Same as 1 except Logarithmic Y tick marks. (The Y data have
61 // to be converted to logarithms separately.)
62 // axis=22 : Same as 2 except Logarithmic Y tick marks. (The Y data have
63 // to be converted to logarithms separately.)
64 // axis=23 : Same as 22, but the grid will be also at the minor ticks.
65 // axis=30 : Same as 0 except Logarithmic X,Y tick marks. (The X,Y data have
66 // to be converted to logarithms separately.)
67 // axis=31 : Same as 1 except Logarithmic X,Y tick marks. (The X,Y data have
68 // to be converted to logarithms separately.)
69 // axis=32 : Same as 2 except Logarithmic X,Y tick marks. (The X,Y data have
70 // to be converted to logarithms separately.)
71 // axis=33 : Same as 32, but the grid will be also at the minor ticks.
72 // axis=40 : Same as 0 except date / time X tick marks.
73 // axis=41 : Same as 1 except date / time X tick marks.
74 // axis=42 : Same as 2 except date / time X tick marks.
75 // axis=43 : Same as 42, but the grid will be also at the minor ticks.
76 // axis=50 : Same as 0 except date / time Y tick marks.
77 // axis=51 : Same as 1 except date / time Y tick marks.
78 // axis=52 : Same as 2 except date / time Y tick marks.
79 // axis=53 : Same as 52, but the grid will be also at the minor ticks.
80 // axis=60 : Same as 0 except date / time X,Y tick marks.
81 // axis=61 : Same as 1 except date / time X,Y tick marks.
82 // axis=62 : Same as 2 except date / time X,Y tick marks.
83 // axis=63 : Same as 62, but the grid will be also at the minor ticks.
84 // axis=70 : Same as 0 except custom X,Y labels.
85 // axis=71 : Same as 1 except custom X,Y labels.
86 // axis=72 : Same as 2 except custom X,Y labels.
87 // axis=73 : Same as 72, but the grid will be also at the minor ticks.
88 //--------------------------------------------------------------------------
89
90 void
91 c_plenv( PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
92 PLINT just, PLINT axis )
93 {
94 c_plenvi( xmin, xmax, ymin, ymax, just, axis, 1 );
95 }
96
97 //--------------------------------------------------------------------------
98 // void plenv0()
99 //
100 // same as plenv() above, but if in multiplot mode does not advance the subpage,
101 // instead clears it.
102 //--------------------------------------------------------------------------
103
104 void
105 c_plenv0( PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
106 PLINT just, PLINT axis )
107 {
108 c_plenvi( xmin, xmax, ymin, ymax, just, axis, 0 );
109 }
110
111
112 static void
113 c_plenvi( PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
114 PLINT just, PLINT axis, PLINT old )
115 {
116 PLFLT lb, rb, tb, bb, dx, dy;
117 PLFLT xsize, ysize, size, xscale, yscale, scale;
118 PLFLT spxmin, spxmax, spymin, spymax;
119 PLFLT vpxmin, vpxmax, vpymin, vpymax;
120
121 if ( plsc->level < 1 )
122 {
123 plabort( "plenv: Please call plinit first" );
124 return;
125 }
126 if ( xmin == xmax )
127 {
128 plabort( "plenv: Invalid xmin and xmax arguments" );
129 return;
130 }
131 if ( ymin == ymax )
132 {
133 plabort( "plenv: Invalid ymin and ymax arguments" );
134 return;
135 }
136 if ( just < -1 || just > 2 )
137 {
138 plabort( "plenv: Invalid just option" );
139 return;
140 }
141
142 if ( plsc->nsubx * plsc->nsuby == 1 ) // not multiplot mode
143 old = 1;
144
145 if ( old == 1 )
146 pladv( 0 );
147 else
148 plclear();
149
150 if ( just == 0 )
151 plvsta();
152 else if ( just == 1 )
153 {
154 lb = 8.0 * plsc->chrht;
155 rb = 5.0 * plsc->chrht;
156 tb = 5.0 * plsc->chrht;
157 bb = 5.0 * plsc->chrht;
158 dx = ABS( xmax - xmin );
159 dy = ABS( ymax - ymin );
160 plgspa( &spxmin, &spxmax, &spymin, &spymax );
161 xsize = spxmax - spxmin;
162 ysize = spymax - spymin;
163 xscale = dx / ( xsize - lb - rb );
164 yscale = dy / ( ysize - tb - bb );
165 scale = MAX( xscale, yscale );
166 vpxmin = MAX( lb, 0.5 * ( xsize - dx / scale ) );
167 vpxmax = vpxmin + ( dx / scale );
168 vpymin = MAX( bb, 0.5 * ( ysize - dy / scale ) );
169 vpymax = vpymin + ( dy / scale );
170 plsvpa( vpxmin, vpxmax, vpymin, vpymax );
171 }
172 else if ( just == 2 )
173 {
174 lb = 8.0 * plsc->chrht;
175 rb = 5.0 * plsc->chrht;
176 tb = 5.0 * plsc->chrht;
177 bb = 5.0 * plsc->chrht;
178 plgspa( &spxmin, &spxmax, &spymin, &spymax );
179 xsize = spxmax - spxmin;
180 ysize = spymax - spymin;
181 size = MIN( xsize - lb - rb, ysize - tb - bb );
182 dx = ( xsize - size - lb - rb ) / 2;
183 vpxmin = lb + dx;
184 vpxmax = vpxmin + size;
185 dy = ( ysize - size - bb - tb ) / 2;
186 vpymin = bb + dy;
187 vpymax = vpymin + size;
188 plsvpa( vpxmin, vpxmax, vpymin, vpymax );
189 }
190
191 plwind( xmin, xmax, ymin, ymax );
192
193 switch ( axis )
194 {
195 case -2:
196 break;
197 case -1:
198 plbox( "bc", (PLFLT) 0.0, 0, "bc", (PLFLT) 0.0, 0 );
199 break;
200 case 0:
201 plbox( "bcnst", (PLFLT) 0.0, 0, "bcnstv", (PLFLT) 0.0, 0 );
202 break;
203 case 1:
204 plbox( "abcnst", (PLFLT) 0.0, 0, "abcnstv", (PLFLT) 0.0, 0 );
205 break;
206 case 2:
207 plbox( "abcgnst", (PLFLT) 0.0, 0, "abcgnstv", (PLFLT) 0.0, 0 );
208 break;
209 case 3:
210 plbox( "abcgnsth", (PLFLT) 0.0, 0, "abcgnstvh", (PLFLT) 0.0, 0 );
211 break;
212 case 10:
213 plbox( "bclnst", (PLFLT) 0.0, 0, "bcnstv", (PLFLT) 0.0, 0 );
214 break;
215 case 11:
216 plbox( "abclnst", (PLFLT) 0.0, 0, "abcnstv", (PLFLT) 0.0, 0 );
217 break;
218 case 12:
219 plbox( "abcglnst", (PLFLT) 0.0, 0, "abcgnstv", (PLFLT) 0.0, 0 );
220 break;
221 case 13:
222 plbox( "abcglnsth", (PLFLT) 0.0, 0, "abcgnstvh", (PLFLT) 0.0, 0 );
223 break;
224 case 20:
225 plbox( "bcnst", (PLFLT) 0.0, 0, "bclnstv", (PLFLT) 0.0, 0 );
226 break;
227 case 21:
228 plbox( "abcnst", (PLFLT) 0.0, 0, "abclnstv", (PLFLT) 0.0, 0 );
229 break;
230 case 22:
231 plbox( "abcgnst", (PLFLT) 0.0, 0, "abcglnstv", (PLFLT) 0.0, 0 );
232 break;
233 case 23:
234 plbox( "abcgnsth", (PLFLT) 0.0, 0, "abcglnstvh", (PLFLT) 0.0, 0 );
235 break;
236 case 30:
237 plbox( "bclnst", (PLFLT) 0.0, 0, "bclnstv", (PLFLT) 0.0, 0 );
238 break;
239 case 31:
240 plbox( "abclnst", (PLFLT) 0.0, 0, "abclnstv", (PLFLT) 0.0, 0 );
241 break;
242 case 32:
243 plbox( "abcglnst", (PLFLT) 0.0, 0, "abcglnstv", (PLFLT) 0.0, 0 );
244 break;
245 case 33:
246 plbox( "abcglnsth", (PLFLT) 0.0, 0, "abcglnstvh", (PLFLT) 0.0, 0 );
247 break;
248 case 40:
249 plbox( "bcdnst", (PLFLT) 0.0, 0, "bcnstv", (PLFLT) 0.0, 0 );
250 break;
251 case 41:
252 plbox( "abcdnst", (PLFLT) 0.0, 0, "abcnstv", (PLFLT) 0.0, 0 );
253 break;
254 case 42:
255 plbox( "abcgdnst", (PLFLT) 0.0, 0, "abcgnstv", (PLFLT) 0.0, 0 );
256 break;
257 case 43:
258 plbox( "abcgdnsth", (PLFLT) 0.0, 0, "abcgnstvh", (PLFLT) 0.0, 0 );
259 break;
260 case 50:
261 plbox( "bcnst", (PLFLT) 0.0, 0, "bcdnstv", (PLFLT) 0.0, 0 );
262 break;
263 case 51:
264 plbox( "abcnst", (PLFLT) 0.0, 0, "abcdnstv", (PLFLT) 0.0, 0 );
265 break;
266 case 52:
267 plbox( "abcgnst", (PLFLT) 0.0, 0, "abcgdnstv", (PLFLT) 0.0, 0 );
268 break;
269 case 53:
270 plbox( "abcgnsth", (PLFLT) 0.0, 0, "abcgdnstvh", (PLFLT) 0.0, 0 );
271 break;
272 case 60:
273 plbox( "bcdnst", (PLFLT) 0.0, 0, "bcdnstv", (PLFLT) 0.0, 0 );
274 break;
275 case 61:
276 plbox( "abcdnst", (PLFLT) 0.0, 0, "abcdnstv", (PLFLT) 0.0, 0 );
277 break;
278 case 62:
279 plbox( "abcgdnst", (PLFLT) 0.0, 0, "abcgdnstv", (PLFLT) 0.0, 0 );
280 break;
281 case 63:
282 plbox( "abcgdnsth", (PLFLT) 0.0, 0, "abcgdnstvh", (PLFLT) 0.0, 0 );
283 break;
284 case 70:
285 plbox( "bcnost", (PLFLT) 0.0, 0, "bcnostv", (PLFLT) 0.0, 0 );
286 break;
287 case 71:
288 plbox( "abcnost", (PLFLT) 0.0, 0, "abcnostv", (PLFLT) 0.0, 0 );
289 break;
290 case 72:
291 plbox( "abcgnost", (PLFLT) 0.0, 0, "abcgnostv", (PLFLT) 0.0, 0 );
292 break;
293 case 73:
294 plbox( "abcgnosth", (PLFLT) 0.0, 0, "abcgnostvh", (PLFLT) 0.0, 0 );
295 break;
296 default:
297 plwarn( "plenv: Invalid axis argument" );
298 }
299 }
300
301 //--------------------------------------------------------------------------
302 // void plvsta()
303 //
304 // Defines a "standard" viewport with seven character heights for
305 // the left margin and four character heights everywhere else.
306 //--------------------------------------------------------------------------
307
308 void
309 c_plvsta( void )
310 {
311 PLFLT xmin, xmax, ymin, ymax;
312 PLFLT lb, rb, tb, bb;
313
314 if ( plsc->level < 1 )
315 {
316 plabort( "plvsta: Please call plinit first" );
317 return;
318 }
319
320 // Find out position of subpage boundaries in millimetres, reduce by
321 // the desired border, and convert back into normalized subpage
322 // coordinates
323
324 lb = 8.0 * plsc->chrht;
325 rb = 5.0 * plsc->chrht;
326 tb = 5.0 * plsc->chrht;
327 bb = 5.0 * plsc->chrht;
328
329 xmin = plP_dcscx( plP_mmdcx( (PLFLT) ( plP_dcmmx( plsc->spdxmi ) + lb ) ) );
330 xmax = plP_dcscx( plP_mmdcx( (PLFLT) ( plP_dcmmx( plsc->spdxma ) - rb ) ) );
331 ymin = plP_dcscy( plP_mmdcy( (PLFLT) ( plP_dcmmy( plsc->spdymi ) + tb ) ) );
332 ymax = plP_dcscy( plP_mmdcy( (PLFLT) ( plP_dcmmy( plsc->spdyma ) - bb ) ) );
333
334 plvpor( xmin, xmax, ymin, ymax );
335 }
336
337 //--------------------------------------------------------------------------
338 // void plvpor()
339 //
340 // Creates a viewport with the specified normalized subpage coordinates.
341 //--------------------------------------------------------------------------
342
343 void
344 c_plvpor( PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax )
345 {
346 if ( plsc->level < 1 )
347 {
348 plabort( "plvpor: Please call plinit first" );
349 return;
350 }
351 if ( ( xmin >= xmax ) || ( ymin >= ymax ) )
352 {
353 plabort( "plvpor: Invalid limits" );
354 return;
355 }
356 if ( ( plsc->cursub <= 0 ) || ( plsc->cursub > ( plsc->nsubx * plsc->nsuby ) ) )
357 {
358 plabort( "plvpor: Please call pladv or plenv to go to a subpage" );
359 return;
360 }
361
362 plsc->vpdxmi = plsc->spdxmi + ( plsc->spdxma - plsc->spdxmi ) * xmin;
363 plsc->vpdxma = plsc->spdxmi + ( plsc->spdxma - plsc->spdxmi ) * xmax;
364 plsc->vpdymi = plsc->spdymi + ( plsc->spdyma - plsc->spdymi ) * ymin;
365 plsc->vpdyma = plsc->spdymi + ( plsc->spdyma - plsc->spdymi ) * ymax;
366
367 plsc->vppxmi = plP_dcpcx( plsc->vpdxmi );
368 plsc->vppxma = plP_dcpcx( plsc->vpdxma );
369 plsc->vppymi = plP_dcpcy( plsc->vpdymi );
370 plsc->vppyma = plP_dcpcy( plsc->vpdyma );
371
372 plsc->clpxmi = MAX( plsc->vppxmi, plsc->phyxmi );
373 plsc->clpxma = MIN( plsc->vppxma, plsc->phyxma );
374 plsc->clpymi = MAX( plsc->vppymi, plsc->phyymi );
375 plsc->clpyma = MIN( plsc->vppyma, plsc->phyyma );
376
377 plsc->level = 2;
378 }
379
380 //--------------------------------------------------------------------------
381 // void plvpas()
382 //
383 // Creates the largest viewport of the specified aspect ratio that fits
384 // within the specified normalized subpage coordinates.
385 //--------------------------------------------------------------------------
386
387 void
388 c_plvpas( PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT aspect )
389 {
390 PLFLT spxmin, spxmax, spymin, spymax;
391 PLFLT vpxmin, vpxmax, vpymin, vpymax;
392 PLFLT xsize, ysize, nxsize, nysize;
393 PLFLT xoffset, yoffset;
394
395 if ( plsc->level < 1 )
396 {
397 plabort( "plvpas: Please call plinit first" );
398 return;
399 }
400 if ( ( xmin >= xmax ) || ( ymin >= ymax ) )
401 {
402 plabort( "plvpas: Invalid limits" );
403 return;
404 }
405
406 if ( aspect <= 0.0 )
407 {
408 c_plvpor( xmin, xmax, ymin, ymax );
409 return;
410 }
411
412 plgspa( &spxmin, &spxmax, &spymin, &spymax );
413
414 xsize = spxmax - spxmin;
415 ysize = spymax - spymin;
416
417 xoffset = xsize * xmin;
418 yoffset = ysize * ymin;
419
420 spxmax = spxmin + xsize * xmax;
421 spxmin = spxmin + xsize * xmin;
422 spymax = spymin + ysize * ymax;
423 spymin = spymin + ysize * ymin;
424
425 // Adjust size for the requested edging
426 xsize = spxmax - spxmin;
427 ysize = spymax - spymin;
428
429 if ( aspect * xsize > ysize )
430 {
431 nxsize = ysize / aspect;
432 nysize = ysize;
433 }
434 else
435 {
436 nxsize = xsize;
437 nysize = xsize * aspect;
438 }
439
440 // center plot within page
441
442 vpxmin = 0.5 * ( xsize - nxsize ) + xoffset;
443 vpxmax = vpxmin + nxsize;
444 vpymin = 0.5 * ( ysize - nysize ) + yoffset;
445 vpymax = vpymin + nysize;
446
447 plsvpa( vpxmin, vpxmax, vpymin, vpymax );
448 }
449
450 //--------------------------------------------------------------------------
451 // void plvasp()
452 //
453 // Sets the edges of the viewport with the given aspect ratio, leaving
454 // room for labels.
455 //--------------------------------------------------------------------------
456
457 void
458 c_plvasp( PLFLT aspect )
459 {
460 PLFLT spxmin, spxmax, spymin, spymax;
461 PLFLT vpxmin, vpxmax, vpymin, vpymax;
462 PLFLT xsize, ysize, nxsize, nysize;
463 PLFLT lb, rb, tb, bb;
464
465 if ( plsc->level < 1 )
466 {
467 plabort( "plvasp: Please call plinit first" );
468 return;
469 }
470
471 lb = 8.0 * plsc->chrht;
472 rb = 5.0 * plsc->chrht;
473 tb = 5.0 * plsc->chrht;
474 bb = 5.0 * plsc->chrht;
475
476 plgspa( &spxmin, &spxmax, &spymin, &spymax );
477 xsize = spxmax - spxmin;
478 ysize = spymax - spymin;
479 xsize -= lb + rb; // adjust for labels
480 ysize -= bb + tb;
481 if ( aspect * xsize > ysize )
482 {
483 nxsize = ysize / aspect;
484 nysize = ysize;
485 }
486 else
487 {
488 nxsize = xsize;
489 nysize = xsize * aspect;
490 }
491
492 // center plot within page
493
494 vpxmin = .5 * ( xsize - nxsize ) + lb;
495 vpxmax = vpxmin + nxsize;
496 vpymin = .5 * ( ysize - nysize ) + bb;
497 vpymax = vpymin + nysize;
498
499 plsvpa( vpxmin, vpxmax, vpymin, vpymax );
500 }
501
502 //--------------------------------------------------------------------------
503 // void plsvpa()
504 //
505 // Sets the edges of the viewport to the specified absolute coordinates
506 // (mm), measured with respect to the current subpage boundaries.
507 //--------------------------------------------------------------------------
508
509 void
510 c_plsvpa( PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax )
511 {
512 PLFLT sxmin, symin;
513
514 if ( plsc->level < 1 )
515 {
516 plabort( "plsvpa: Please call plinit first" );
517 return;
518 }
519 if ( ( xmin >= xmax ) || ( ymin >= ymax ) )
520 {
521 plabort( "plsvpa: Invalid limits" );
522 return;
523 }
524 if ( ( plsc->cursub <= 0 ) || ( plsc->cursub > ( plsc->nsubx * plsc->nsuby ) ) )
525 {
526 plabort( "plsvpa: Please call pladv or plenv to go to a subpage" );
527 return;
528 }
529
530 sxmin = plP_dcmmx( plsc->spdxmi );
531 symin = plP_dcmmy( plsc->spdymi );
532
533 plsc->vpdxmi = plP_mmdcx( (PLFLT) ( sxmin + xmin ) );
534 plsc->vpdxma = plP_mmdcx( (PLFLT) ( sxmin + xmax ) );
535 plsc->vpdymi = plP_mmdcy( (PLFLT) ( symin + ymin ) );
536 plsc->vpdyma = plP_mmdcy( (PLFLT) ( symin + ymax ) );
537
538 plsc->vppxmi = plP_dcpcx( plsc->vpdxmi );
539 plsc->vppxma = plP_dcpcx( plsc->vpdxma );
540 plsc->vppymi = plP_dcpcy( plsc->vpdymi );
541 plsc->vppyma = plP_dcpcy( plsc->vpdyma );
542
543 plsc->clpxmi = plP_dcpcx( plsc->vpdxmi );
544 plsc->clpxma = plP_dcpcx( plsc->vpdxma );
545 plsc->clpymi = plP_dcpcy( plsc->vpdymi );
546 plsc->clpyma = plP_dcpcy( plsc->vpdyma );
547
548 plsc->level = 2;
549 }