PLplot
5.10.0
|
00001 // Vector plotting routines. 00002 // 00003 // Copyright (C) 2004 Andrew Ross 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 #define NEED_PLDEBUG 00023 #include "plplotP.h" 00024 #include <float.h> 00025 #include <ctype.h> 00026 00027 // Static function prototypes 00028 00029 static void plP_plotvect( PLFLT x, PLFLT y, PLFLT u, PLFLT v, PLFLT scale ); 00030 00031 //-------------------------------------------------------------------------- 00032 // void c_plsvect() 00033 // 00034 // Set the style of the arrow used by plvect 00035 //-------------------------------------------------------------------------- 00036 00037 void 00038 c_plsvect( const PLFLT *arrowx, const PLFLT *arrowy, PLINT npts, PLINT fill ) 00039 { 00040 int i; 00041 PLFLT def_arrow_x[6] = { -0.5, 0.5, 0.3, 0.5, 0.3, 0.5 }; 00042 PLFLT def_arrow_y[6] = { 0.0, 0.0, 0.2, 0.0, -0.2, 0.0 }; 00043 00044 if ( plsc->arrow_x ) 00045 free_mem( plsc->arrow_x ); 00046 if ( plsc->arrow_y ) 00047 free_mem( plsc->arrow_y ); 00048 00049 // Reset default arrow if null pointers are passed. 00050 if ( arrowx == NULL && arrowy == NULL ) 00051 { 00052 arrowx = def_arrow_x; 00053 arrowy = def_arrow_y; 00054 npts = 6; 00055 fill = 0; 00056 } 00057 00058 if ( ( ( plsc->arrow_x = (PLFLT *) malloc( (size_t) npts * sizeof ( PLFLT ) ) ) == NULL ) || 00059 ( ( plsc->arrow_y = (PLFLT *) malloc( (size_t) npts * sizeof ( PLFLT ) ) ) == NULL ) ) 00060 { 00061 plexit( "c_plsvect: Insufficient memory" ); 00062 } 00063 00064 plsc->arrow_npts = npts; 00065 plsc->arrow_fill = fill; 00066 for ( i = 0; i < npts; i++ ) 00067 { 00068 plsc->arrow_x[i] = arrowx[i]; 00069 plsc->arrow_y[i] = arrowy[i]; 00070 } 00071 } 00072 00073 // 00074 // Plot an individual vector 00075 // 00076 static void 00077 plP_plotvect( PLFLT x, PLFLT y, PLFLT u, PLFLT v, PLFLT scale ) 00078 { 00079 PLFLT uu, vv, px0, py0, dpx, dpy; 00080 PLFLT xt, yt; 00081 // Unnecessarily initialize a_y to quiet a -O1 -Wuninitialized warning 00082 // which is a false alarm. (If something goes wrong with the 00083 // a_x malloc below any further use of a_y does not occur.) 00084 PLINT *a_x, *a_y = NULL; 00085 int j; 00086 00087 uu = scale * u; 00088 vv = scale * v; 00089 00090 if ( uu == 0.0 && vv == 0.0 ) 00091 return; 00092 00093 if ( ( ( a_x = (PLINT *) malloc( sizeof ( PLINT ) * (size_t) ( plsc->arrow_npts ) ) ) == NULL ) || 00094 ( ( a_y = (PLINT *) malloc( sizeof ( PLINT ) * (size_t) ( plsc->arrow_npts ) ) ) == NULL ) ) 00095 { 00096 plexit( "plP_plotvect: Insufficient memory" ); 00097 } 00098 00099 TRANSFORM( x, y, &xt, &yt ); 00100 px0 = plP_wcpcx( xt ); 00101 py0 = plP_wcpcy( yt ); 00102 00103 pldebug( "plP_plotvect", "%f %f %d %d\n", x, y, px0, py0 ); 00104 00105 TRANSFORM( x + 0.5 * uu, y + 0.5 * vv, &xt, &yt ); 00106 //printf("plvect: %f %f %f %f %f %f %f\n",scale, x,0.5*uu, y,0.5*vv, xt, yt); 00107 dpx = plP_wcpcx( xt ) - px0; 00108 dpy = plP_wcpcy( yt ) - py0; 00109 00110 // transform arrow -> a 00111 00112 for ( j = 0; j < plsc->arrow_npts; j++ ) 00113 { 00114 a_x[j] = (PLINT) ( plsc->arrow_x[j] * dpx - plsc->arrow_y[j] * dpy + px0 ); 00115 a_y[j] = (PLINT) ( plsc->arrow_x[j] * dpy + plsc->arrow_y[j] * dpx + py0 ); 00116 } 00117 00118 // draw the arrow 00119 plP_draphy_poly( a_x, a_y, plsc->arrow_npts ); 00120 if ( plsc->arrow_fill ) 00121 { 00122 plP_plfclp( a_x, a_y, plsc->arrow_npts, plsc->clpxmi, plsc->clpxma, 00123 plsc->clpymi, plsc->clpyma, plP_fill ); 00124 } 00125 00126 free( (void *) a_x ); 00127 free( (void *) a_y ); 00128 } 00129 00130 // 00131 // void plfvect() 00132 // 00133 // Routine to plot a vector array with arbitrary coordinate 00134 // and vector transformations 00135 // 00136 void plfvect( PLFLT ( *getuv )( PLINT, PLINT, PLPointer ), 00137 PLPointer up, PLPointer vp, 00138 PLINT nx, PLINT ny, PLFLT scale, 00139 void ( *pltr )( PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer ), 00140 PLPointer pltr_data ) 00141 { 00142 PLINT i, j, i1, j1; 00143 PLFLT **u, **v, **x, **y; 00144 PLFLT lscale, dx, dy, dxmin, dymin, umax, vmax; 00145 00146 plAlloc2dGrid( &u, nx, ny ); 00147 plAlloc2dGrid( &v, nx, ny ); 00148 plAlloc2dGrid( &x, nx, ny ); 00149 plAlloc2dGrid( &y, nx, ny ); 00150 00151 for ( j = 0; j < ny; j++ ) 00152 { 00153 for ( i = 0; i < nx; i++ ) 00154 { 00155 u[i][j] = getuv( i, j, up ); 00156 v[i][j] = getuv( i, j, vp ); 00157 pltr( (PLFLT) i, (PLFLT) j, &x[i][j], &y[i][j], pltr_data ); 00158 } 00159 } 00160 00161 // Calculate apropriate scaling if necessary 00162 if ( scale <= 0.0 ) 00163 { 00164 if ( nx <= 1 && ny <= 1 ) 00165 { 00166 fprintf( stderr, "plfvect: not enough points for autoscaling\n" ); 00167 return; 00168 } 00169 dxmin = 10E10; 00170 dymin = 10E10; 00171 for ( j = 0; j < ny; j++ ) 00172 { 00173 for ( i = 0; i < nx; i++ ) 00174 { 00175 for ( j1 = j; j1 < ny; j1++ ) 00176 { 00177 for ( i1 = 0; i1 < nx; i1++ ) 00178 { 00179 dx = fabs( x[i1][j1] - x[i][j] ); 00180 dy = fabs( y[i1][j1] - y[i][j] ); 00181 if ( dx > 0 ) 00182 { 00183 dxmin = ( dx < dxmin ) ? dx : dxmin; 00184 } 00185 if ( dy > 0 ) 00186 { 00187 dymin = ( dy < dymin ) ? dy : dymin; 00188 } 00189 } 00190 } 00191 } 00192 } 00193 umax = u[0][0]; 00194 vmax = v[0][0]; 00195 for ( j = 0; j < ny; j++ ) 00196 { 00197 for ( i = 0; i < nx; i++ ) 00198 { 00199 umax = ( u[i][j] > umax ) ? u[i][j] : umax; 00200 vmax = ( v[i][j] > vmax ) ? v[i][j] : vmax; 00201 } 00202 } 00203 if ( umax != 0.0 ) 00204 { 00205 dxmin = dxmin / umax; 00206 } 00207 else 00208 { 00209 dxmin = 10E10; 00210 } 00211 if ( vmax != 0.0 ) 00212 { 00213 dymin = dymin / vmax; 00214 } 00215 else 00216 { 00217 dymin = 10E10; 00218 } 00219 lscale = 1.5 * MIN( dxmin, dymin ); 00220 if ( scale < 0.0 ) 00221 { 00222 scale = -scale * lscale; 00223 } 00224 else 00225 { 00226 scale = lscale; 00227 } 00228 } 00229 00230 for ( j = 0; j < ny; j++ ) 00231 { 00232 for ( i = 0; i < nx; i++ ) 00233 { 00234 plP_plotvect( x[i][j], y[i][j], u[i][j], v[i][j], scale ); 00235 } 00236 } 00237 00238 plFree2dGrid( u, nx, ny ); 00239 plFree2dGrid( v, nx, ny ); 00240 plFree2dGrid( x, nx, ny ); 00241 plFree2dGrid( y, nx, ny ); 00242 } 00243 00244 void 00245 c_plvect( const PLFLT * const *u, const PLFLT * const *v, PLINT nx, PLINT ny, PLFLT scale, 00246 void ( *pltr )( PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer ), 00247 PLPointer pltr_data ) 00248 { 00249 plfvect( plf2eval1, (PLPointer) u, (PLPointer) v, 00250 nx, ny, scale, pltr, pltr_data ); 00251 }