00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #define NEED_PLDEBUG
00025 #include "plplotP.h"
00026 #include <float.h>
00027 #include <ctype.h>
00028
00029
00030
00031 static void plP_plotvect( PLFLT x, PLFLT y, PLFLT u, PLFLT v, PLFLT scale );
00032
00033
00034
00035
00036
00037
00038
00039 void
00040 c_plsvect( const PLFLT *arrowx, const 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
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
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
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
00116
00117
00118
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
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( const PLFLT **u, const 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 }