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