PLplot  5.10.0
plvect.c
Go to the documentation of this file.
00001 //      Vector plotting routines.
00002 //
00003 // Copyright (C) 2004  Andrew Ross
00004 //
00005 // This file is part of PLplot.
00006 //
00007 // PLplot is free software; you can redistribute it and/or modify
00008 // it under the terms of the GNU Library General Public License as published
00009 // by the Free Software Foundation; either version 2 of the License, or
00010 // (at your option) any later version.
00011 //
00012 // PLplot is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU Library General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU Library General Public License
00018 // along with PLplot; if not, write to the Free Software
00019 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020 //
00021 
00022 #define NEED_PLDEBUG
00023 #include "plplotP.h"
00024 #include <float.h>
00025 #include <ctype.h>
00026 
00027 // Static function prototypes
00028 
00029 static void plP_plotvect( PLFLT x, PLFLT y, PLFLT u, PLFLT v, PLFLT scale );
00030 
00031 //--------------------------------------------------------------------------
00032 // void c_plsvect()
00033 //
00034 // Set the style of the arrow used by plvect
00035 //--------------------------------------------------------------------------
00036 
00037 void
00038 c_plsvect( const PLFLT *arrowx, const PLFLT *arrowy, PLINT npts, PLINT fill )
00039 {
00040     int   i;
00041     PLFLT def_arrow_x[6] = { -0.5, 0.5, 0.3, 0.5, 0.3, 0.5 };
00042     PLFLT def_arrow_y[6] = { 0.0, 0.0, 0.2, 0.0, -0.2, 0.0 };
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     // Reset default arrow if null pointers are passed.
00050     if ( arrowx == NULL && arrowy == NULL )
00051     {
00052         arrowx = def_arrow_x;
00053         arrowy = def_arrow_y;
00054         npts   = 6;
00055         fill   = 0;
00056     }
00057 
00058     if ( ( ( plsc->arrow_x = (PLFLT *) malloc( (size_t) npts * sizeof ( PLFLT ) ) ) == NULL ) ||
00059          ( ( plsc->arrow_y = (PLFLT *) malloc( (size_t) npts * sizeof ( PLFLT ) ) ) == NULL ) )
00060     {
00061         plexit( "c_plsvect: Insufficient memory" );
00062     }
00063 
00064     plsc->arrow_npts = npts;
00065     plsc->arrow_fill = fill;
00066     for ( i = 0; i < npts; i++ )
00067     {
00068         plsc->arrow_x[i] = arrowx[i];
00069         plsc->arrow_y[i] = arrowy[i];
00070     }
00071 }
00072 
00073 //
00074 // Plot an individual vector
00075 //
00076 static void
00077 plP_plotvect( PLFLT x, PLFLT y, PLFLT u, PLFLT v, PLFLT scale )
00078 {
00079     PLFLT uu, vv, px0, py0, dpx, dpy;
00080     PLFLT xt, yt;
00081     // Unnecessarily initialize a_y to quiet a -O1 -Wuninitialized warning
00082     // which is a false alarm.  (If something goes wrong with the
00083     // a_x malloc below any further use of a_y does not occur.)
00084     PLINT *a_x, *a_y = NULL;
00085     int   j;
00086 
00087     uu = scale * u;
00088     vv = scale * v;
00089 
00090     if ( uu == 0.0 && vv == 0.0 )
00091         return;
00092 
00093     if ( ( ( a_x = (PLINT *) malloc( sizeof ( PLINT ) * (size_t) ( plsc->arrow_npts ) ) ) == NULL ) ||
00094          ( ( a_y = (PLINT *) malloc( sizeof ( PLINT ) * (size_t) ( plsc->arrow_npts ) ) ) == NULL ) )
00095     {
00096         plexit( "plP_plotvect: Insufficient memory" );
00097     }
00098 
00099     TRANSFORM( x, y, &xt, &yt );
00100     px0 = plP_wcpcx( xt );
00101     py0 = plP_wcpcy( yt );
00102 
00103     pldebug( "plP_plotvect", "%f %f %d %d\n", x, y, px0, py0 );
00104 
00105     TRANSFORM( x + 0.5 * uu, y + 0.5 * vv, &xt, &yt );
00106     //printf("plvect: %f %f %f %f %f %f %f\n",scale, x,0.5*uu, y,0.5*vv, xt, yt);
00107     dpx = plP_wcpcx( xt ) - px0;
00108     dpy = plP_wcpcy( yt ) - py0;
00109 
00110     // transform arrow -> a
00111 
00112     for ( j = 0; j < plsc->arrow_npts; j++ )
00113     {
00114         a_x[j] = (PLINT) ( plsc->arrow_x[j] * dpx - plsc->arrow_y[j] * dpy + px0 );
00115         a_y[j] = (PLINT) ( plsc->arrow_x[j] * dpy + plsc->arrow_y[j] * dpx + py0 );
00116     }
00117 
00118     // draw the arrow
00119     plP_draphy_poly( a_x, a_y, plsc->arrow_npts );
00120     if ( plsc->arrow_fill )
00121     {
00122         plP_plfclp( a_x, a_y, plsc->arrow_npts, plsc->clpxmi, plsc->clpxma,
00123             plsc->clpymi, plsc->clpyma, plP_fill );
00124     }
00125 
00126     free( (void *) a_x );
00127     free( (void *) a_y );
00128 }
00129 
00130 //
00131 // void plfvect()
00132 //
00133 // Routine to plot a vector array with arbitrary coordinate
00134 // and vector transformations
00135 //
00136 void plfvect( PLFLT ( *getuv )( PLINT, PLINT, PLPointer ),
00137               PLPointer up, PLPointer vp,
00138               PLINT nx, PLINT ny, PLFLT scale,
00139               void ( *pltr )( PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer ),
00140               PLPointer pltr_data )
00141 {
00142     PLINT i, j, i1, j1;
00143     PLFLT **u, **v, **x, **y;
00144     PLFLT lscale, dx, dy, dxmin, dymin, umax, vmax;
00145 
00146     plAlloc2dGrid( &u, nx, ny );
00147     plAlloc2dGrid( &v, nx, ny );
00148     plAlloc2dGrid( &x, nx, ny );
00149     plAlloc2dGrid( &y, nx, ny );
00150 
00151     for ( j = 0; j < ny; j++ )
00152     {
00153         for ( i = 0; i < nx; i++ )
00154         {
00155             u[i][j] = getuv( i, j, up );
00156             v[i][j] = getuv( i, j, vp );
00157             pltr( (PLFLT) i, (PLFLT) j, &x[i][j], &y[i][j], pltr_data );
00158         }
00159     }
00160 
00161     // Calculate apropriate scaling if necessary
00162     if ( scale <= 0.0 )
00163     {
00164         if ( nx <= 1 && ny <= 1 )
00165         {
00166             fprintf( stderr, "plfvect: not enough points for autoscaling\n" );
00167             return;
00168         }
00169         dxmin = 10E10;
00170         dymin = 10E10;
00171         for ( j = 0; j < ny; j++ )
00172         {
00173             for ( i = 0; i < nx; i++ )
00174             {
00175                 for ( j1 = j; j1 < ny; j1++ )
00176                 {
00177                     for ( i1 = 0; i1 < nx; i1++ )
00178                     {
00179                         dx = fabs( x[i1][j1] - x[i][j] );
00180                         dy = fabs( y[i1][j1] - y[i][j] );
00181                         if ( dx > 0 )
00182                         {
00183                             dxmin = ( dx < dxmin ) ? dx : dxmin;
00184                         }
00185                         if ( dy > 0 )
00186                         {
00187                             dymin = ( dy < dymin ) ? dy : dymin;
00188                         }
00189                     }
00190                 }
00191             }
00192         }
00193         umax = u[0][0];
00194         vmax = v[0][0];
00195         for ( j = 0; j < ny; j++ )
00196         {
00197             for ( i = 0; i < nx; i++ )
00198             {
00199                 umax = ( u[i][j] > umax ) ? u[i][j] : umax;
00200                 vmax = ( v[i][j] > vmax ) ? v[i][j] : vmax;
00201             }
00202         }
00203         if ( umax != 0.0 )
00204         {
00205             dxmin = dxmin / umax;
00206         }
00207         else
00208         {
00209             dxmin = 10E10;
00210         }
00211         if ( vmax != 0.0 )
00212         {
00213             dymin = dymin / vmax;
00214         }
00215         else
00216         {
00217             dymin = 10E10;
00218         }
00219         lscale = 1.5 * MIN( dxmin, dymin );
00220         if ( scale < 0.0 )
00221         {
00222             scale = -scale * lscale;
00223         }
00224         else
00225         {
00226             scale = lscale;
00227         }
00228     }
00229 
00230     for ( j = 0; j < ny; j++ )
00231     {
00232         for ( i = 0; i < nx; i++ )
00233         {
00234             plP_plotvect( x[i][j], y[i][j], u[i][j], v[i][j], scale );
00235         }
00236     }
00237 
00238     plFree2dGrid( u, nx, ny );
00239     plFree2dGrid( v, nx, ny );
00240     plFree2dGrid( x, nx, ny );
00241     plFree2dGrid( y, nx, ny );
00242 }
00243 
00244 void
00245 c_plvect( const PLFLT * const *u, const PLFLT * const *v, PLINT nx, PLINT ny, PLFLT scale,
00246           void ( *pltr )( PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer ),
00247           PLPointer pltr_data )
00248 {
00249     plfvect( plf2eval1, (PLPointer) u, (PLPointer) v,
00250         nx, ny, scale, pltr, pltr_data );
00251 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines