PLplot  5.10.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
plwind.c
Go to the documentation of this file.
1 // Routines for setting up world coordinates of the current viewport.
2 //
3 // Copyright (C) 2004-2014 Alan W. Irwin
4 //
5 // This file is part of PLplot.
6 //
7 // PLplot is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU Library General Public License as published
9 // by the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
11 //
12 // PLplot is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Library General Public License for more details.
16 //
17 // You should have received a copy of the GNU Library General Public License
18 // along with PLplot; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 //
21 
22 #include "plplotP.h"
23 
24 #define dtr 0.01745329252
25 
26 //--------------------------------------------------------------------------
27 // void plwind()
28 //
29 // Set up world coordinates of the viewport boundaries (2d plots).
30 //--------------------------------------------------------------------------
31 
32 void
34 {
35  PLFLT dx, dy, mmxmi, mmxma, mmymi, mmyma;
36  PLFLT xvpwxmin, xvpwxmax, xvpwymin, xvpwymax;
37  PLWindow w;
38 
39  if ( plsc->level < 2 )
40  {
41  plabort( "plwind: Please set up viewport first" );
42  return;
43  }
44 
45 // Best to just warn and recover on bounds errors
46 
47  if ( xmin == xmax )
48  {
49  plwarn( "plwind: Invalid window limits in x." );
50  xmin--; xmax++;
51  }
52  if ( ymin == ymax )
53  {
54  plwarn( "plwind: Invalid window limits in y." );
55  ymin--; ymax++;
56  }
57 
58  plsc->vpwxmi = xmin;
59  plsc->vpwxma = xmax;
60  plsc->vpwymi = ymin;
61  plsc->vpwyma = ymax;
62 
63 // The true plot window is made slightly larger than requested so that
64 // the end limits will be on the graph
65 // Get the (slightly extended) window limits.
66  plP_xgvpw( &xvpwxmin, &xvpwxmax, &xvpwymin, &xvpwymax );
67 
68 // Compute the scaling between coordinate systems
69 
70  dx = xvpwxmax - xvpwxmin;
71  dy = xvpwymax - xvpwymin;
72 
73  plsc->wpxscl = ( plsc->vppxma - plsc->vppxmi ) / dx;
74  plsc->wpxoff = ( xmax * plsc->vppxmi - xmin * plsc->vppxma ) / dx;
75  plsc->wpyscl = ( plsc->vppyma - plsc->vppymi ) / dy;
76  plsc->wpyoff = ( ymax * plsc->vppymi - ymin * plsc->vppyma ) / dy;
77 
78  mmxmi = plP_dcmmx( plsc->vpdxmi );
79  mmxma = plP_dcmmx( plsc->vpdxma );
80  mmymi = plP_dcmmy( plsc->vpdymi );
81  mmyma = plP_dcmmy( plsc->vpdyma );
82 
83 // Set transformation variables for world coordinates to mm
84 
85  plsc->wmxscl = ( mmxma - mmxmi ) / dx;
86  plsc->wmxoff = ( xmax * mmxmi - xmin * mmxma ) / dx;
87  plsc->wmyscl = ( mmyma - mmymi ) / dy;
88  plsc->wmyoff = ( ymax * mmymi - ymin * mmyma ) / dy;
89 
90 // Set transformation variables for world coordinates to device coords
91 
92  plsc->wdxscl = plsc->wmxscl * plsc->xpmm / ( plsc->phyxma - plsc->phyxmi );
93  plsc->wdxoff = plsc->wmxoff * plsc->xpmm / ( plsc->phyxma - plsc->phyxmi );
94  plsc->wdyscl = plsc->wmyscl * plsc->ypmm / ( plsc->phyyma - plsc->phyymi );
95  plsc->wdyoff = plsc->wmyoff * plsc->ypmm / ( plsc->phyyma - plsc->phyymi );
96 
97 // Register plot window attributes
98 
99  w.dxmi = plsc->vpdxmi;
100  w.dxma = plsc->vpdxma;
101  w.dymi = plsc->vpdymi;
102  w.dyma = plsc->vpdyma;
103 
104  w.wxmi = xvpwxmin;
105  w.wxma = xvpwxmax;
106  w.wymi = xvpwymin;
107  w.wyma = xvpwymax;
108 
109  plP_swin( &w );
110 
111 // Go to level 3
112 
113  plsc->level = 3;
114 }
115 
116 //--------------------------------------------------------------------------
117 // void plw3d()
118 //
119 // Set up a window for three-dimensional plotting. The data are mapped
120 // into a box with world coordinate size "basex" by "basey" by "height",
121 // with the base being symmetrically positioned about zero. Thus
122 // the mapping between data 3-d and world 3-d coordinates is given by:
123 //
124 // x = xmin => wx = -0.5*basex
125 // x = xmax => wx = 0.5*basex
126 // y = ymin => wy = -0.5*basey
127 // y = ymax => wy = 0.5*basey
128 // z = zmin => wz = 0.0
129 // z = zmax => wz = height
130 //
131 // The world coordinate box is then viewed from position "alt"-"az",
132 // measured in degrees. For proper operation, 0 <= alt <= 90 degrees,
133 // but az can be any value.
134 //--------------------------------------------------------------------------
135 
136 void
138  PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin,
139  PLFLT zmax, PLFLT alt, PLFLT az )
140 {
141  PLFLT xmin_adjusted, xmax_adjusted, ymin_adjusted, ymax_adjusted, zmin_adjusted, zmax_adjusted, d;
142  PLFLT cx, cy, saz, caz, salt, calt, zscale;
143 
144  if ( plsc->level < 3 )
145  {
146  plabort( "plw3d: Please set up 2-d window first" );
147  return;
148  }
149  if ( basex <= 0.0 || basey <= 0.0 || height <= 0.0 )
150  {
151  plabort( "plw3d: Invalid world coordinate boxsize" );
152  return;
153  }
154  if ( xmin == xmax || ymin == ymax || zmin == zmax )
155  {
156  plabort( "plw3d: Invalid axis range" );
157  return;
158  }
159  if ( alt < 0.0 || alt > 90.0 )
160  {
161  plabort( "plw3d: Altitude must be between 0 and 90 degrees" );
162  return;
163  }
164 
165  d = 1.0e-5 * ( xmax - xmin );
166  xmax_adjusted = xmax + d;
167  xmin_adjusted = xmin - d;
168  d = 1.0e-5 * ( ymax - ymin );
169  ymax_adjusted = ymax + d;
170  ymin_adjusted = ymin - d;
171  d = 1.0e-5 * ( zmax - zmin );
172  zmax_adjusted = zmax + d;
173  zmin_adjusted = zmin - d;
174  cx = basex / ( xmax_adjusted - xmin_adjusted );
175  cy = basey / ( ymax_adjusted - ymin_adjusted );
176  zscale = height / ( zmax_adjusted - zmin_adjusted );
177  saz = sin( dtr * az );
178  caz = cos( dtr * az );
179  salt = sin( dtr * alt );
180  calt = cos( dtr * alt );
181 
182  plsc->domxmi = xmin_adjusted;
183  plsc->domxma = xmax_adjusted;
184  plsc->domymi = ymin_adjusted;
185  plsc->domyma = ymax_adjusted;
186  plsc->zzscl = zscale;
187  plsc->ranmi = zmin_adjusted;
188  plsc->ranma = zmax_adjusted;
189 
190  plsc->base3x = basex;
191  plsc->base3y = basey;
192  plsc->basecx = 0.5 * ( xmin_adjusted + xmax_adjusted );
193  plsc->basecy = 0.5 * ( ymin_adjusted + ymax_adjusted );
194 // Mathematical explanation of the 3 transformations of coordinates:
195 // (I) Scaling:
196 // x' = cx*(x-x_mid) = cx*(x-plsc->basecx)
197 // y' = cy*(y-y_mid) = cy*(y-plsc->basecy)
198 // z' = zscale*(z-zmin_adjusted) = zscale*(z-plsc->ranmi)
199 // (II) Rotation about z' axis clockwise by the angle of the azimut when
200 // looking from the top in a right-handed coordinate system.
201 // x'' x'
202 // y'' = M_1 * y'
203 // z'' z'
204 // where the rotation matrix M_1 (see any mathematical physics book such
205 // as Mathematical Methods in the Physical Sciences by Boas) is
206 // caz -saz 0
207 // saz caz 0
208 // 0 0 1
209 // (III) Rotation about x'' axis by 90 deg - alt to bring z''' axis
210 // coincident with line of sight and x''' and y''' corresponding to
211 // x and y coordinates in the 2D plane of the plot.
212 // x''' x''
213 // y''' = M_2 * y''
214 // z''' z''
215 // where the rotation matrix M_2 is
216 // 1 0 0
217 // 0 salt calt
218 // 0 -calt salt
219 // Note
220 // x''' x'
221 // y''' = M * y'
222 // z''' z'
223 // where M = M_2*M_1 is given by
224 // caz -saz 0
225 // salt*saz salt*caz calt
226 // -calt*saz -calt*caz salt
227 // plP_w3wcx and plP_w3wcy take the combination of the plsc->basecx,
228 // plsc->basecy, plsc->ranmi, plsc->cxx, plsc->cxy, plsc->cyx, plsc->cyy, and
229 // plsc->cyz data stored here to implement the combination of the 3
230 // transformations to determine x''' and y''' from x, y, and z.
231 //
232  plsc->cxx = cx * caz;
233  plsc->cxy = -cy * saz;
234  plsc->cyx = cx * saz * salt;
235  plsc->cyy = cy * caz * salt;
236  plsc->cyz = zscale * calt;
237  plsc->czx = -cx * calt * saz;
238  plsc->czy = -cy * calt * caz;
239  plsc->czz = zscale * salt;
240 }