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