PLplot: plvect.c Source File

PLplot 5.10.0

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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