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(PLFLT *arrowx, PLFLT *arrowy, PLINT npts, PLINT fill) {
00041 int i;
00042
00043 if (plsc->arrow_x) free_mem(plsc->arrow_x);
00044 if (plsc->arrow_y) free_mem(plsc->arrow_y);
00045
00046 if (((plsc->arrow_x = (PLFLT *)malloc(npts*sizeof(PLFLT)))==NULL)||
00047 ((plsc->arrow_y = (PLFLT *)malloc(npts*sizeof(PLFLT)))==NULL))
00048 {
00049 plexit("c_plsvect: Insufficient memory");
00050 }
00051
00052 plsc->arrow_npts = npts;
00053 plsc->arrow_fill = fill;
00054 for (i=0; i<npts; i++) {
00055 plsc->arrow_x[i] = arrowx[i];
00056 plsc->arrow_y[i] = arrowy[i];
00057 }
00058 }
00059
00060
00061
00062
00063 static void
00064 plP_plotvect(PLFLT x, PLFLT y, PLFLT u, PLFLT v, PLFLT scale) {
00065
00066 PLFLT uu, vv, px0, py0, dpx, dpy;
00067 PLINT *a_x, *a_y;
00068 int j;
00069
00070 uu = scale*u;
00071 vv = scale*v;
00072
00073 if(uu == 0.0 && vv == 0.0) return;
00074
00075 if (((a_x = (PLINT *)malloc(sizeof(PLINT)*(plsc->arrow_npts)))==NULL)||
00076 ((a_y = (PLINT *)malloc(sizeof(PLINT)*(plsc->arrow_npts)))==NULL))
00077 {
00078 plexit("plP_plotvect: Insufficient memory");
00079 }
00080
00081 px0 = plP_wcpcx(x);
00082 py0 = plP_wcpcy(y);
00083
00084 pldebug("plP_plotvect", "%f %f %d %d\n",x,y,px0,py0);
00085
00086 dpx = plP_wcpcx(x + 0.5*uu) - px0;
00087 dpy = plP_wcpcy(y + 0.5*vv) - py0;
00088
00089
00090
00091 for (j = 0; j < plsc->arrow_npts; j++) {
00092 a_x[j] = (PLINT)(plsc->arrow_x[j] * dpx - plsc->arrow_y[j] * dpy + px0);
00093 a_y[j] = (PLINT)(plsc->arrow_x[j] * dpy + plsc->arrow_y[j] * dpx + py0);
00094 }
00095
00096
00097 plP_draphy_poly(a_x,a_y,plsc->arrow_npts);
00098 if (plsc->arrow_fill) {
00099 plP_plfclp(a_x, a_y, plsc->arrow_npts, plsc->clpxmi, plsc->clpxma,
00100 plsc->clpymi, plsc->clpyma, plP_fill);
00101 }
00102
00103 free((void *)a_x);
00104 free((void *)a_y);
00105
00106 }
00107
00108
00109
00110
00111
00112
00113
00114 void plfvect(PLFLT (*plf2eval) (PLINT, PLINT, PLPointer),
00115 PLPointer f2eval_data1, PLPointer f2eval_data2,
00116 PLINT nx, PLINT ny, PLFLT scale,
00117 void (*pltr) (PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer),
00118 PLPointer pltr_data) {
00119 PLINT i, j, i1, j1;
00120 PLFLT **u, **v, **x, **y;
00121 PLFLT lscale, dx, dy, dxmin, dymin, umax, vmax;
00122
00123 plAlloc2dGrid(&u, nx, ny);
00124 plAlloc2dGrid(&v, nx, ny);
00125 plAlloc2dGrid(&x, nx, ny);
00126 plAlloc2dGrid(&y, nx, ny);
00127
00128 for (j=0; j<ny; j++) {
00129 for (i=0 ;i<nx ;i++) {
00130 u[i][j] = plf2eval(i,j,f2eval_data1);
00131 v[i][j] = plf2eval(i,j,f2eval_data2);
00132 pltr((PLFLT) i, (PLFLT) j, &x[i][j], &y[i][j], pltr_data);
00133 }
00134 }
00135
00136
00137 if (scale <= 0.0 ) {
00138 if (nx <= 1 && ny <= 1) {
00139 fprintf(stderr,"plfvect: not enough points for autoscaling\n");
00140 return;
00141 }
00142 dxmin = 10E10;
00143 dymin = 10E10;
00144 for (j=0; j<ny; j++) {
00145 for (i=0 ;i<nx ;i++) {
00146 for (j1=j; j1<ny; j1++) {
00147 for (i1=0 ;i1<nx ;i1++) {
00148 dx = fabs(x[i1][j1]-x[i][j]);
00149 dy = fabs(y[i1][j1]-y[i][j]);
00150 if (dx > 0) {
00151 dxmin = (dx<dxmin)?dx:dxmin;
00152 }
00153 if (dy > 0) {
00154 dymin = (dy<dymin)?dy:dymin;
00155 }
00156 }
00157 }
00158 }
00159 }
00160 umax = u[0][0];
00161 vmax = v[0][0];
00162 for (j=0; j<ny; j++) {
00163 for (i=0 ;i<nx ;i++) {
00164 umax = (u[i][j]>umax)?u[i][j]:umax;
00165 vmax = (v[i][j]>vmax)?v[i][j]:vmax;
00166 }
00167 }
00168 umax = umax/dxmin;
00169 vmax = vmax/dymin;
00170 lscale = (umax<vmax)?umax:vmax;
00171 lscale = 1.5/lscale;
00172 if (scale < 0.0) {
00173 scale = -scale*lscale;
00174 }
00175 else {
00176 scale = lscale;
00177 }
00178 }
00179
00180 for (j=0; j<ny; j++) {
00181 for (i=0 ;i<nx ;i++) {
00182 plP_plotvect(x[i][j],y[i][j],u[i][j],v[i][j],scale);
00183 }
00184 }
00185
00186 plFree2dGrid(u, nx, ny);
00187 plFree2dGrid(v, nx, ny);
00188 plFree2dGrid(x, nx, ny);
00189 plFree2dGrid(y, nx, ny);
00190
00191 }
00192
00193 void
00194 c_plvect(PLFLT **u, PLFLT **v, PLINT nx, PLINT ny, PLFLT scale,
00195 void (*pltr) (PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer),
00196 PLPointer pltr_data)
00197 {
00198 PLfGrid2 grid1, grid2;
00199
00200 grid1.f = u;
00201 grid2.f = v;
00202
00203 plfvect(plf2eval2, (PLPointer) &grid1, (PLPointer) &grid2,
00204 nx, ny, scale, pltr, pltr_data);
00205 }