PLplot  5.9.9
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
plvect.c
Go to the documentation of this file.
1 // $Id: plvect.c 12095 2011-12-03 08:56:15Z andrewross $
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 
44  if ( plsc->arrow_x )
45  free_mem( plsc->arrow_x );
46  if ( plsc->arrow_y )
47  free_mem( plsc->arrow_y );
48 
49  if ( ( ( plsc->arrow_x = (PLFLT *) malloc( (size_t) npts * sizeof ( PLFLT ) ) ) == NULL ) ||
50  ( ( plsc->arrow_y = (PLFLT *) malloc( (size_t) npts * sizeof ( PLFLT ) ) ) == NULL ) )
51  {
52  plexit( "c_plsvect: Insufficient memory" );
53  }
54 
55  plsc->arrow_npts = npts;
56  plsc->arrow_fill = fill;
57  for ( i = 0; i < npts; i++ )
58  {
59  plsc->arrow_x[i] = arrowx[i];
60  plsc->arrow_y[i] = arrowy[i];
61  }
62 }
63 
64 //
65 // Plot an individual vector
66 //
67 static void
69 {
70  PLFLT uu, vv, px0, py0, dpx, dpy;
71  PLINT *a_x, *a_y;
72  int j;
73 
74  uu = scale * u;
75  vv = scale * v;
76 
77  if ( uu == 0.0 && vv == 0.0 )
78  return;
79 
80  if ( ( ( a_x = (PLINT *) malloc( sizeof ( PLINT ) * (size_t) ( plsc->arrow_npts ) ) ) == NULL ) ||
81  ( ( a_y = (PLINT *) malloc( sizeof ( PLINT ) * (size_t) ( plsc->arrow_npts ) ) ) == NULL ) )
82  {
83  plexit( "plP_plotvect: Insufficient memory" );
84  }
85 
86  px0 = plP_wcpcx( x );
87  py0 = plP_wcpcy( y );
88 
89  pldebug( "plP_plotvect", "%f %f %d %d\n", x, y, px0, py0 );
90 
91  dpx = plP_wcpcx( x + 0.5 * uu ) - px0;
92  dpy = plP_wcpcy( y + 0.5 * vv ) - py0;
93 
94  // transform arrow -> a
95 
96  for ( j = 0; j < plsc->arrow_npts; j++ )
97  {
98  a_x[j] = (PLINT) ( plsc->arrow_x[j] * dpx - plsc->arrow_y[j] * dpy + px0 );
99  a_y[j] = (PLINT) ( plsc->arrow_x[j] * dpy + plsc->arrow_y[j] * dpx + py0 );
100  }
101 
102  // draw the arrow
103  plP_draphy_poly( a_x, a_y, plsc->arrow_npts );
104  if ( plsc->arrow_fill )
105  {
106  plP_plfclp( a_x, a_y, plsc->arrow_npts, plsc->clpxmi, plsc->clpxma,
107  plsc->clpymi, plsc->clpyma, plP_fill );
108  }
109 
110  free( (void *) a_x );
111  free( (void *) a_y );
112 }
113 
114 //
115 // void plfvect()
116 //
117 // Routine to plot a vector array with arbitrary coordinate
118 // and vector transformations
119 //
120 void plfvect( PLFLT ( *getuv )( PLINT, PLINT, PLPointer ),
121  PLPointer up, PLPointer vp,
122  PLINT nx, PLINT ny, PLFLT scale,
123  void ( *pltr )( PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer ),
124  PLPointer pltr_data )
125 {
126  PLINT i, j, i1, j1;
127  PLFLT **u, **v, **x, **y;
128  PLFLT lscale, dx, dy, dxmin, dymin, umax, vmax;
129 
130  plAlloc2dGrid( &u, nx, ny );
131  plAlloc2dGrid( &v, nx, ny );
132  plAlloc2dGrid( &x, nx, ny );
133  plAlloc2dGrid( &y, nx, ny );
134 
135  for ( j = 0; j < ny; j++ )
136  {
137  for ( i = 0; i < nx; i++ )
138  {
139  u[i][j] = getuv( i, j, up );
140  v[i][j] = getuv( i, j, vp );
141  pltr( (PLFLT) i, (PLFLT) j, &x[i][j], &y[i][j], pltr_data );
142  }
143  }
144 
145  // Calculate apropriate scaling if necessary
146  if ( scale <= 0.0 )
147  {
148  if ( nx <= 1 && ny <= 1 )
149  {
150  fprintf( stderr, "plfvect: not enough points for autoscaling\n" );
151  return;
152  }
153  dxmin = 10E10;
154  dymin = 10E10;
155  for ( j = 0; j < ny; j++ )
156  {
157  for ( i = 0; i < nx; i++ )
158  {
159  for ( j1 = j; j1 < ny; j1++ )
160  {
161  for ( i1 = 0; i1 < nx; i1++ )
162  {
163  dx = fabs( x[i1][j1] - x[i][j] );
164  dy = fabs( y[i1][j1] - y[i][j] );
165  if ( dx > 0 )
166  {
167  dxmin = ( dx < dxmin ) ? dx : dxmin;
168  }
169  if ( dy > 0 )
170  {
171  dymin = ( dy < dymin ) ? dy : dymin;
172  }
173  }
174  }
175  }
176  }
177  umax = u[0][0];
178  vmax = v[0][0];
179  for ( j = 0; j < ny; j++ )
180  {
181  for ( i = 0; i < nx; i++ )
182  {
183  umax = ( u[i][j] > umax ) ? u[i][j] : umax;
184  vmax = ( v[i][j] > vmax ) ? v[i][j] : vmax;
185  }
186  }
187  umax = umax / dxmin;
188  vmax = vmax / dymin;
189  lscale = ( umax < vmax ) ? umax : vmax;
190  lscale = 1.5 / lscale;
191  if ( scale < 0.0 )
192  {
193  scale = -scale * lscale;
194  }
195  else
196  {
197  scale = lscale;
198  }
199  }
200 
201  for ( j = 0; j < ny; j++ )
202  {
203  for ( i = 0; i < nx; i++ )
204  {
205  plP_plotvect( x[i][j], y[i][j], u[i][j], v[i][j], scale );
206  }
207  }
208 
209  plFree2dGrid( u, nx, ny );
210  plFree2dGrid( v, nx, ny );
211  plFree2dGrid( x, nx, ny );
212  plFree2dGrid( y, nx, ny );
213 }
214 
215 void
216 c_plvect( const PLFLT * const *u, const PLFLT * const *v, PLINT nx, PLINT ny, PLFLT scale,
217  void ( *pltr )( PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer ),
218  PLPointer pltr_data )
219 {
221  nx, ny, scale, pltr, pltr_data );
222 }
void plFree2dGrid(PLFLT **f, PLINT nx, PLINT PL_UNUSED(ny))
Definition: pdfutils.c:1130
void PLFLT PLINT PLINT PLFLT PLFLT PLFLT PLFLT PLINT PLINT PLINT PLFLT PLFLT PLINT PLFLT PLINT const PLINT const char *const PLINT nx
PLINT plP_wcpcx(PLFLT x)
Definition: plcvt.c:65
void c_plvect(const PLFLT *const *u, const PLFLT *const *v, PLINT nx, PLINT ny, PLFLT scale, void(*pltr)(PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer), PLPointer pltr_data)
Definition: plvect.c:216
void PLFLT PLINT PLINT PLFLT x
void plAlloc2dGrid(PLFLT ***f, PLINT nx, PLINT ny)
Definition: pdfutils.c:1104
void * PLPointer
Definition: plplot.h:201
int PLINT
Definition: plplot.h:175
static void pltr(PLFLT x, PLFLT y, PLFLT *tx, PLFLT *ty, void *pltr_data)
Definition: f77/sccont.c:211
void c_plsvect(const PLFLT *arrowx, const PLFLT *arrowy, PLINT npts, PLINT fill)
Definition: plvect.c:40
void PLFLT PLINT PLINT PLFLT PLFLT y
PLFLT plf2eval1(PLINT ix, PLINT iy, PLPointer plf2eval_data)
Definition: plcont.c:416
void plfvect(PLFLT(*getuv)(PLINT, PLINT, PLPointer), PLPointer up, PLPointer vp, PLINT nx, PLINT ny, PLFLT scale, void(*pltr)(PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer), PLPointer pltr_data)
Definition: plvect.c:120
static void plP_plotvect(PLFLT x, PLFLT y, PLFLT u, PLFLT v, PLFLT scale)
Definition: plvect.c:68
void plP_fill(short *x, short *y, PLINT npts)
Definition: plcore.c:428
float PLFLT
Definition: plplot.h:159
void plP_draphy_poly(PLINT *x, PLINT *y, PLINT n)
Definition: plline.c:529
#define free_mem(a)
Definition: plplotP.h:187
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:533
PLINT plP_wcpcy(PLFLT y)
Definition: plcvt.c:75
dx
if { $zoomopts($this,1) == 0 } then {
Definition: Plframe.py:613
void plexit(const char *errormsg)
Definition: plctrl.c:1941