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