PLplot 5.15.0
Loading...
Searching...
No Matches
plvect.c
Go to the documentation of this file.
1// Vector plotting routines.
2//
3// Copyright (C) 2004 Andrew Ross
4//
5// This file is part of PLplot.
6//
7// PLplot is free software; you can redistribute it and/or modify
8// it under the terms of the GNU Library General Public License as published
9// by the Free Software Foundation; either version 2 of the License, or
10// (at your option) any later version.
11//
12// PLplot is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15// GNU Library General Public License for more details.
16//
17// You should have received a copy of the GNU Library General Public License
18// along with PLplot; if not, write to the Free Software
19// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20//
21
22#define NEED_PLDEBUG
23#include "plplotP.h"
24#include <float.h>
25#include <ctype.h>
26
27// Static function prototypes
28
29static void plP_plotvect( PLFLT x, PLFLT y, PLFLT u, PLFLT v, PLFLT scale );
30
31//--------------------------------------------------------------------------
32// N.B. This routine only needed by the Fortran interface to distinguish
33// the case where both arrowx and arrowy are NULL. So don't put declaration in
34// header which might encourage others to use this in some other context.
35//--------------------------------------------------------------------------
36PLDLLIMPEXP void
38{
39 c_plsvect( NULL, NULL, 0, 0 );
40}
41
42//--------------------------------------------------------------------------
43// void c_plsvect()
44//
45// Set the style of the arrow used by plvect
46//--------------------------------------------------------------------------
47
48void
49c_plsvect( PLFLT_VECTOR arrowx, PLFLT_VECTOR arrowy, PLINT npts, PLBOOL fill )
50{
51 int i;
52 PLFLT def_arrow_x[6] = { -0.5, 0.5, 0.3, 0.5, 0.3, 0.5 };
53 PLFLT def_arrow_y[6] = { 0.0, 0.0, 0.2, 0.0, -0.2, 0.0 };
54
55 if ( plsc->arrow_x )
56 free_mem( plsc->arrow_x );
57 if ( plsc->arrow_y )
58 free_mem( plsc->arrow_y );
59
60 // Reset default arrow if null pointers are passed.
61 if ( arrowx == NULL && arrowy == NULL )
62 {
63 arrowx = def_arrow_x;
64 arrowy = def_arrow_y;
65 npts = 6;
66 fill = 0;
67 }
68
69 if ( ( ( plsc->arrow_x = (PLFLT *) malloc( (size_t) npts * sizeof ( PLFLT ) ) ) == NULL ) ||
70 ( ( plsc->arrow_y = (PLFLT *) malloc( (size_t) npts * sizeof ( PLFLT ) ) ) == NULL ) )
71 {
72 plexit( "c_plsvect: Insufficient memory" );
73 }
74
75 plsc->arrow_npts = npts;
76 plsc->arrow_fill = fill;
77 for ( i = 0; i < npts; i++ )
78 {
79 plsc->arrow_x[i] = arrowx[i];
80 plsc->arrow_y[i] = arrowy[i];
81 }
82}
83
84//
85// Plot an individual vector
86//
87static void
89{
90 PLFLT uu, vv, px0, py0, dpx, dpy;
91 PLFLT xt, yt;
92 // Unnecessarily initialize a_y to quiet a -O1 -Wuninitialized warning
93 // which is a false alarm. (If something goes wrong with the
94 // a_x malloc below any further use of a_y does not occur.)
95 PLINT *a_x, *a_y = NULL;
96 int j;
97
98 uu = scale * u;
99 vv = scale * v;
100
101 if ( uu == 0.0 && vv == 0.0 )
102 return;
103
104 if ( ( ( a_x = (PLINT *) malloc( sizeof ( PLINT ) * (size_t) ( plsc->arrow_npts ) ) ) == NULL ) ||
105 ( ( a_y = (PLINT *) malloc( sizeof ( PLINT ) * (size_t) ( plsc->arrow_npts ) ) ) == NULL ) )
106 {
107 plexit( "plP_plotvect: Insufficient memory" );
108 }
109
110 TRANSFORM( x, y, &xt, &yt );
111 px0 = plP_wcpcx( xt );
112 py0 = plP_wcpcy( yt );
113
114 pldebug( "plP_plotvect", "%f %f %d %d\n", x, y, px0, py0 );
115
116 TRANSFORM( x + 0.5 * uu, y + 0.5 * vv, &xt, &yt );
117 //printf("plvect: %f %f %f %f %f %f %f\n",scale, x,0.5*uu, y,0.5*vv, xt, yt);
118 dpx = plP_wcpcx( xt ) - px0;
119 dpy = plP_wcpcy( yt ) - py0;
120
121 // transform arrow -> a
122
123 for ( j = 0; j < plsc->arrow_npts; j++ )
124 {
125 a_x[j] = (PLINT) ( plsc->arrow_x[j] * dpx - plsc->arrow_y[j] * dpy + px0 );
126 a_y[j] = (PLINT) ( plsc->arrow_x[j] * dpy + plsc->arrow_y[j] * dpx + py0 );
127 }
128
129 // draw the arrow
130 plP_draphy_poly( a_x, a_y, plsc->arrow_npts );
131 if ( plsc->arrow_fill )
132 {
133 plP_plfclp( a_x, a_y, plsc->arrow_npts, plsc->clpxmi, plsc->clpxma,
134 plsc->clpymi, plsc->clpyma, plP_fill );
135 }
136
137 free( (void *) a_x );
138 free( (void *) a_y );
139}
140
141//
142// void plfvect()
143//
144// Routine to plot a vector array with arbitrary coordinate
145// and vector transformations
146//
148 PLINT nx, PLINT ny, PLFLT scale,
149 PLTRANSFORM_callback pltr, PLPointer pltr_data )
150{
151 PLINT i, j, i1, j1;
152 PLFLT **u, **v, **x, **y;
153 PLFLT lscale, dx, dy, dxmin, dymin, umax, vmax;
154
155 if ( pltr == NULL )
156 {
157 // If pltr is undefined, abort with an error.
158 plabort( "plfvect: The pltr callback must be defined" );
159 return;
160 }
161
162 plAlloc2dGrid( &u, nx, ny );
163 plAlloc2dGrid( &v, nx, ny );
164 plAlloc2dGrid( &x, nx, ny );
165 plAlloc2dGrid( &y, nx, ny );
166
167 for ( j = 0; j < ny; j++ )
168 {
169 for ( i = 0; i < nx; i++ )
170 {
171 u[i][j] = getuv( i, j, up );
172 v[i][j] = getuv( i, j, vp );
173 pltr( (PLFLT) i, (PLFLT) j, &x[i][j], &y[i][j], pltr_data );
174 }
175 }
176
177 // Calculate apropriate scaling if necessary
178 if ( scale <= 0.0 )
179 {
180 if ( nx <= 1 && ny <= 1 )
181 {
182 fprintf( stderr, "plfvect: not enough points for autoscaling\n" );
183 return;
184 }
185 dxmin = 10E10;
186 dymin = 10E10;
187 for ( j = 0; j < ny; j++ )
188 {
189 for ( i = 0; i < nx; i++ )
190 {
191 for ( j1 = j; j1 < ny; j1++ )
192 {
193 for ( i1 = 0; i1 < nx; i1++ )
194 {
195 dx = fabs( x[i1][j1] - x[i][j] );
196 dy = fabs( y[i1][j1] - y[i][j] );
197 if ( dx > 0 )
198 {
199 dxmin = ( dx < dxmin ) ? dx : dxmin;
200 }
201 if ( dy > 0 )
202 {
203 dymin = ( dy < dymin ) ? dy : dymin;
204 }
205 }
206 }
207 }
208 }
209 umax = u[0][0];
210 vmax = v[0][0];
211 for ( j = 0; j < ny; j++ )
212 {
213 for ( i = 0; i < nx; i++ )
214 {
215 umax = ( u[i][j] > umax ) ? u[i][j] : umax;
216 vmax = ( v[i][j] > vmax ) ? v[i][j] : vmax;
217 }
218 }
219 if ( umax != 0.0 )
220 {
221 dxmin = dxmin / umax;
222 }
223 else
224 {
225 dxmin = 10E10;
226 }
227 if ( vmax != 0.0 )
228 {
229 dymin = dymin / vmax;
230 }
231 else
232 {
233 dymin = 10E10;
234 }
235 lscale = 1.5 * MIN( dxmin, dymin );
236 if ( scale < 0.0 )
237 {
238 scale = -scale * lscale;
239 }
240 else
241 {
242 scale = lscale;
243 }
244 }
245
246 for ( j = 0; j < ny; j++ )
247 {
248 for ( i = 0; i < nx; i++ )
249 {
250 plP_plotvect( x[i][j], y[i][j], u[i][j], v[i][j], scale );
251 }
252 }
253
254 plFree2dGrid( u, nx, ny );
255 plFree2dGrid( v, nx, ny );
256 plFree2dGrid( x, nx, ny );
257 plFree2dGrid( y, nx, ny );
258}
259
260void
262 PLTRANSFORM_callback pltr, PLPointer pltr_data )
263{
265 nx, ny, scale, pltr, pltr_data );
266}
#define MIN(a, b)
Definition: dsplint.c:29
PLFLT plf2eval1(PLINT ix, PLINT iy, PLPointer plf2eval_data)
Definition: plcont.c:410
void plP_fill(short *x, short *y, PLINT npts)
Definition: plcore.c:451
void plexit(PLCHAR_VECTOR errormsg)
Definition: plctrl.c:1958
void plabort(PLCHAR_VECTOR errormsg)
Definition: plctrl.c:1894
PLINT plP_wcpcy(PLFLT y)
Definition: plcvt.c:73
PLINT plP_wcpcx(PLFLT x)
Definition: plcvt.c:63
#define PLDLLIMPEXP
Definition: pldll.h:49
void plP_plfclp(PLINT *x, PLINT *y, PLINT npts, PLINT xmin, PLINT xmax, PLINT ymin, PLINT ymax, void(*draw)(short *, short *, PLINT))
Definition: plfill.c:538
void plP_draphy_poly(PLINT *x, PLINT *y, PLINT n)
Definition: plline.c:527
void plFree2dGrid(PLFLT **f, PLINT nx, PLINT PL_UNUSED(ny))
Definition: plmem.c:116
void plAlloc2dGrid(PLFLT ***f, PLINT nx, PLINT ny)
Definition: plmem.c:91
#define TRANSFORM(x, y, xnew, ynew)
Definition: plplotP.h:214
#define free_mem(a)
Definition: plplotP.h:182
PLFLT(* PLF2EVAL_callback)(PLINT ix, PLINT iy, PLPointer data)
Definition: plplot.h:259
float PLFLT
Definition: plplot.h:163
void(* PLTRANSFORM_callback)(PLFLT x, PLFLT y, PLFLT_NC_SCALAR xp, PLFLT_NC_SCALAR yp, PLPointer data)
Definition: plplot.h:257
const PLFLT * PLFLT_VECTOR
Definition: plplot.h:244
const PLFLT *const * PLFLT_MATRIX
Definition: plplot.h:253
int PLINT
Definition: plplot.h:181
void * PLPointer
Definition: plplot.h:209
PLINT PLBOOL
Definition: plplot.h:204
void c_plsvect(PLFLT_VECTOR arrowx, PLFLT_VECTOR arrowy, PLINT npts, PLBOOL fill)
Definition: plvect.c:49
void plfvect(PLF2EVAL_callback getuv, PLPointer up, PLPointer vp, PLINT nx, PLINT ny, PLFLT scale, PLTRANSFORM_callback pltr, PLPointer pltr_data)
Definition: plvect.c:147
PLDLLIMPEXP void plsvect_null(void)
Definition: plvect.c:37
void c_plvect(PLFLT_MATRIX u, PLFLT_MATRIX v, PLINT nx, PLINT ny, PLFLT scale, PLTRANSFORM_callback pltr, PLPointer pltr_data)
Definition: plvect.c:261
static void plP_plotvect(PLFLT x, PLFLT y, PLFLT u, PLFLT v, PLFLT scale)
Definition: plvect.c:88