PLplot 5.9.6
|
00001 /* $Id$ 00002 * 00003 * Routines for setting up world coordinates of the current viewport. 00004 * 00005 * Copyright (C) 2004 Alan W. Irwin 00006 * 00007 * This file is part of PLplot. 00008 * 00009 * PLplot is free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Library Public License as published 00011 * by the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * PLplot is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU Library General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU Library General Public License 00020 * along with PLplot; if not, write to the Free Software 00021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00022 */ 00023 00024 #include "plplotP.h" 00025 00026 #define dtr 0.01745329252 00027 00028 /*--------------------------------------------------------------------------*\ 00029 * void plwind() 00030 * 00031 * Set up world coordinates of the viewport boundaries (2d plots). 00032 \*--------------------------------------------------------------------------*/ 00033 00034 void 00035 c_plwind( PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax ) 00036 { 00037 PLFLT dx, dy, mmxmi, mmxma, mmymi, mmyma; 00038 PLFLT xvpwxmin, xvpwxmax, xvpwymin, xvpwymax; 00039 PLWindow w; 00040 00041 if ( plsc->level < 2 ) 00042 { 00043 plabort( "plwind: Please set up viewport first" ); 00044 return; 00045 } 00046 00047 /* Best to just warn and recover on bounds errors */ 00048 00049 if ( xmin == xmax ) 00050 { 00051 plwarn( "plwind: Invalid window limits in x." ); 00052 xmin--; xmax++; 00053 } 00054 if ( ymin == ymax ) 00055 { 00056 plwarn( "plwind: Invalid window limits in y." ); 00057 ymin--; ymax++; 00058 } 00059 00060 plsc->vpwxmi = xmin; 00061 plsc->vpwxma = xmax; 00062 plsc->vpwymi = ymin; 00063 plsc->vpwyma = ymax; 00064 00065 /* The true plot window is made slightly larger than requested so that */ 00066 /* the end limits will be on the graph */ 00067 /* Get the (slightly extended) window limits. */ 00068 plP_xgvpw( &xvpwxmin, &xvpwxmax, &xvpwymin, &xvpwymax ); 00069 00070 /* Compute the scaling between coordinate systems */ 00071 00072 dx = xvpwxmax - xvpwxmin; 00073 dy = xvpwymax - xvpwymin; 00074 00075 plsc->wpxscl = ( plsc->vppxma - plsc->vppxmi ) / dx; 00076 plsc->wpxoff = ( xmax * plsc->vppxmi - xmin * plsc->vppxma ) / dx; 00077 plsc->wpyscl = ( plsc->vppyma - plsc->vppymi ) / dy; 00078 plsc->wpyoff = ( ymax * plsc->vppymi - ymin * plsc->vppyma ) / dy; 00079 00080 mmxmi = plP_dcmmx( plsc->vpdxmi ); 00081 mmxma = plP_dcmmx( plsc->vpdxma ); 00082 mmymi = plP_dcmmy( plsc->vpdymi ); 00083 mmyma = plP_dcmmy( plsc->vpdyma ); 00084 00085 /* Set transformation variables for world coordinates to mm */ 00086 00087 plsc->wmxscl = ( mmxma - mmxmi ) / dx; 00088 plsc->wmxoff = ( xmax * mmxmi - xmin * mmxma ) / dx; 00089 plsc->wmyscl = ( mmyma - mmymi ) / dy; 00090 plsc->wmyoff = ( ymax * mmymi - ymin * mmyma ) / dy; 00091 00092 /* Set transformation variables for world coordinates to device coords */ 00093 00094 plsc->wdxscl = plsc->wmxscl * plsc->xpmm / ( plsc->phyxma - plsc->phyxmi ); 00095 plsc->wdxoff = plsc->wmxoff * plsc->xpmm / ( plsc->phyxma - plsc->phyxmi ); 00096 plsc->wdyscl = plsc->wmyscl * plsc->ypmm / ( plsc->phyyma - plsc->phyymi ); 00097 plsc->wdyoff = plsc->wmyoff * plsc->ypmm / ( plsc->phyyma - plsc->phyymi ); 00098 00099 /* Register plot window attributes */ 00100 00101 w.dxmi = plsc->vpdxmi; 00102 w.dxma = plsc->vpdxma; 00103 w.dymi = plsc->vpdymi; 00104 w.dyma = plsc->vpdyma; 00105 00106 w.wxmi = xvpwxmin; 00107 w.wxma = xvpwxmax; 00108 w.wymi = xvpwymin; 00109 w.wyma = xvpwymax; 00110 00111 plP_swin( &w ); 00112 00113 /* Go to level 3 */ 00114 00115 plsc->level = 3; 00116 } 00117 00118 /*--------------------------------------------------------------------------*\ 00119 * void plw3d() 00120 * 00121 * Set up a window for three-dimensional plotting. The data are mapped 00122 * into a box with world coordinate size "basex" by "basey" by "height", 00123 * with the base being symmetrically positioned about zero. Thus 00124 * the mapping between data 3-d and world 3-d coordinates is given by: 00125 * 00126 * x = xmin => wx = -0.5*basex 00127 * x = xmax => wx = 0.5*basex 00128 * y = ymin => wy = -0.5*basey 00129 * y = ymax => wy = 0.5*basey 00130 * z = zmin => wz = 0.0 00131 * z = zmax => wz = height 00132 * 00133 * The world coordinate box is then viewed from position "alt"-"az", 00134 * measured in degrees. For proper operation, 0 <= alt <= 90 degrees, 00135 * but az can be any value. 00136 \*--------------------------------------------------------------------------*/ 00137 00138 void 00139 c_plw3d( PLFLT basex, PLFLT basey, PLFLT height, PLFLT xmin0, 00140 PLFLT xmax0, PLFLT ymin0, PLFLT ymax0, PLFLT zmin0, 00141 PLFLT zmax0, PLFLT alt, PLFLT az ) 00142 { 00143 PLFLT xmin, xmax, ymin, ymax, zmin, zmax, d; 00144 PLFLT cx, cy, saz, caz, salt, calt, zscale; 00145 00146 if ( plsc->level < 3 ) 00147 { 00148 plabort( "plw3d: Please set up 2-d window first" ); 00149 return; 00150 } 00151 if ( basex <= 0.0 || basey <= 0.0 || height <= 0.0 ) 00152 { 00153 plabort( "plw3d: Invalid world coordinate boxsize" ); 00154 return; 00155 } 00156 if ( xmin0 == xmax0 || ymin0 == ymax0 || zmin0 == zmax0 ) 00157 { 00158 plabort( "plw3d: Invalid axis range" ); 00159 return; 00160 } 00161 if ( alt < 0.0 || alt > 90.0 ) 00162 { 00163 plabort( "plw3d: Altitude must be between 0 and 90 degrees" ); 00164 return; 00165 } 00166 00167 d = 1.0e-5 * ( xmax0 - xmin0 ); 00168 xmax = xmax0 + d; 00169 xmin = xmin0 - d; 00170 d = 1.0e-5 * ( ymax0 - ymin0 ); 00171 ymax = ymax0 + d; 00172 ymin = ymin0 - d; 00173 d = 1.0e-5 * ( zmax0 - zmin0 ); 00174 zmax = zmax0 + d; 00175 zmin = zmin0 - d; 00176 cx = basex / ( xmax - xmin ); 00177 cy = basey / ( ymax - ymin ); 00178 zscale = height / ( zmax - zmin ); 00179 saz = sin( dtr * az ); 00180 caz = cos( dtr * az ); 00181 salt = sin( dtr * alt ); 00182 calt = cos( dtr * alt ); 00183 00184 plsc->domxmi = xmin; 00185 plsc->domxma = xmax; 00186 plsc->domymi = ymin; 00187 plsc->domyma = ymax; 00188 plsc->zzscl = zscale; 00189 plsc->ranmi = zmin; 00190 plsc->ranma = zmax; 00191 00192 plsc->base3x = basex; 00193 plsc->base3y = basey; 00194 plsc->basecx = 0.5 * ( xmin + xmax ); 00195 plsc->basecy = 0.5 * ( ymin + ymax ); 00196 /* Mathematical explanation of the 3 transformations of coordinates: 00197 * (I) Scaling: 00198 * x' = cx*(x-x_mid) = cx*(x-plsc->basecx) 00199 * y' = cy*(y-y_mid) = cy*(y-plsc->basecy) 00200 * z' = zscale*(z-zmin) = zscale*(z-plsc->ranmi) 00201 * (II) Rotation about z' axis clockwise by the angle of the azimut when 00202 * looking from the top in a right-handed coordinate system. 00203 * x'' x' 00204 * y'' = M_1 * y' 00205 * z'' z' 00206 * where the rotation matrix M_1 (see any mathematical physics book such 00207 * as Mathematical Methods in the Physical Sciences by Boas) is 00208 * caz -saz 0 00209 * saz caz 0 00210 * 0 0 1 00211 * (III) Rotation about x'' axis by 90 deg - alt to bring z''' axis 00212 * coincident with line of sight and x''' and y''' corresponding to 00213 * x and y coordinates in the 2D plane of the plot. 00214 * x''' x'' 00215 * y''' = M_2 * y'' 00216 * z''' z'' 00217 * where the rotation matrix M_2 is 00218 * 1 0 0 00219 * 0 salt calt 00220 * 0 -calt salt 00221 * Note 00222 * x''' x' 00223 * y''' = M * y' 00224 * z''' z' 00225 * where M = M_2*M_1 is given by 00226 * caz -saz 0 00227 * salt*saz salt*caz calt 00228 * -calt*saz -calt*caz salt 00229 * plP_w3wcx and plP_w3wcy take the combination of the plsc->basecx, 00230 * plsc->basecy, plsc->ranmi, plsc->cxx, plsc->cxy, plsc->cyx, plsc->cyy, and 00231 * plsc->cyz data stored here to implement the combination of the 3 00232 * transformations to determine x''' and y''' from x, y, and z. 00233 */ 00234 plsc->cxx = cx * caz; 00235 plsc->cxy = -cy * saz; 00236 plsc->cyx = cx * saz * salt; 00237 plsc->cyy = cy * caz * salt; 00238 plsc->cyz = zscale * calt; 00239 plsc->czx = -cx * calt * saz; 00240 plsc->czy = -cy * calt * caz; 00241 plsc->czz = zscale * salt; 00242 }