00001
00002
00003
00004
00005
00006
00007 #include <math.h>
00008 #include <stdio.h>
00009 #include <string.h>
00010 #include "math_graphics.h"
00011 #include "PloEch.h"
00012
00013 #include "GetProperty.h"
00014 #include "SetProperty.h"
00015 #include "DrawObjects.h"
00016 #include "BuildObjects.h"
00017 #include "Axes.h"
00018 #include "Xcall1.h"
00019 #include "Champ.h"
00020 #include "sciprint.h"
00021 #include "periScreen.h"
00022 #include "CurrentObjectsManagement.h"
00023
00024
00025 #include "MALLOC.h"
00026
00027 static double MiniD __PARAMS((double *x,integer n));
00028 extern void initsubwin();
00029
00030 extern void compute_data_bounds2(int cflag,char dataflag,char *logflags,double *x,double *y,int n1,int n2,double *drect);
00031 extern BOOL update_specification_bounds(sciPointObj *psubwin, double *rect,int flag);
00032 extern int re_index_brect(double * brect, double * drect);
00033 extern BOOL strflag2axes_properties(sciPointObj * psubwin, char * strflag);
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 void champg(char *name, integer colored, double *x, double *y, double *fx, double *fy, integer *n1,
00053 integer *n2, char *strflag, double *brect, double *arfact, integer lstr)
00054 {
00055 integer n;
00056 double xx[2],yy[2];
00057 integer nn1=1,nn2=2;
00058
00059 sciPointObj *psubwin;
00060 integer flag,type =1;
00061 double arsize1;
00062 integer *style;
00063 integer i;
00064 double drect[6];
00065 BOOL bounds_changed = FALSE;
00066 BOOL axes_properties_changed = FALSE;
00067
00068
00069 int typeofchamp = ( colored == 0 ? 0 : 1 ) ;
00070
00071
00072 integer verbose=0,narg,xz[10],uc;
00073
00074 C2F(dr)("xget","use color",&verbose, &uc, &narg,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
00075 if (uc)
00076 C2F(dr)("xget","color",&verbose,xz,&narg,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
00077 else
00078 C2F(dr)("xget","line style",&verbose,xz,&narg,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
00080 n=2*(*n1)*((*n2)+1);
00081
00082
00083 getChampDataBounds( x, y, fx, fy, *n1, *n2,typeofchamp, &(xx[0]), &(xx[1]), &(yy[0]), &(yy[1]) ) ;
00084
00085
00086 psubwin = sciGetCurrentSubWin() ;
00087 checkRedrawing() ;
00088
00089
00090 if (sciGetSurface(psubwin) == (sciPointObj *) NULL)
00091 {
00092 pSUBWIN_FEATURE (psubwin)->is3d = FALSE;
00093 pSUBWIN_FEATURE (psubwin)->project[2]= 0;
00094 }
00095 else
00096 {
00097 pSUBWIN_FEATURE (psubwin)->theta_kp=pSUBWIN_FEATURE (psubwin)->theta;
00098 pSUBWIN_FEATURE (psubwin)->alpha_kp=pSUBWIN_FEATURE (psubwin)->alpha;
00099 }
00100
00101 pSUBWIN_FEATURE (psubwin)->alpha = 0.0;
00102 pSUBWIN_FEATURE (psubwin)->theta = 270.0;
00103
00104
00105
00106
00107
00108 sciSetIsClipping (psubwin,0);
00109
00110
00111 if (sciGetGraphicMode (psubwin)->autoscaling)
00112 {
00113
00114 switch (strflag[1]) {
00115 case '0':
00116
00117 break;
00118 case '1' : case '3' : case '5' : case '7':
00119
00120 re_index_brect(brect,drect);
00121 break;
00122 case '2' : case '4' : case '6' : case '8': case '9':
00123
00124 compute_data_bounds2(0,'g',pSUBWIN_FEATURE (psubwin)->logflags,xx,yy,nn1,nn2,drect);
00125 break;
00126 }
00127 if (!pSUBWIN_FEATURE(psubwin)->FirstPlot &&
00128 (strflag[1] == '7' || strflag[1] == '8'|| strflag[1] == '9')) {
00129 drect[0] = Min(pSUBWIN_FEATURE(psubwin)->SRect[0],drect[0]);
00130 drect[2] = Min(pSUBWIN_FEATURE(psubwin)->SRect[2],drect[2]);
00131 drect[1] = Max(pSUBWIN_FEATURE(psubwin)->SRect[1],drect[1]);
00132 drect[3] = Max(pSUBWIN_FEATURE(psubwin)->SRect[3],drect[3]);
00133 }
00134
00135 if (strflag[1] != '0')
00136 {
00137 bounds_changed = update_specification_bounds(psubwin, drect,2);
00138 }
00139 }
00140
00141 if(pSUBWIN_FEATURE (psubwin)->FirstPlot == TRUE) bounds_changed = TRUE;
00142
00143 axes_properties_changed = strflag2axes_properties(psubwin, strflag);
00144
00145 pSUBWIN_FEATURE (psubwin)->FirstPlot = FALSE;
00146
00147 if( bounds_changed || axes_properties_changed )
00148 {
00149 sciDrawObj(sciGetCurrentFigure());
00150 }
00151
00152 flag = 1;
00153 arsize1 = *arfact;
00154
00155
00156 if ((style = MALLOC ((*n1) * sizeof (integer))) == NULL)
00157 {
00158 sciprint("No more memory available\n");
00159 return;
00160 }
00161
00162 for(i=0;i<(*n1);i++) { style[i] = i ; }
00163
00164 sciSetCurrentObj(ConstructSegs(psubwin,type,x,y,*n1,*n2,fx,fy,flag,
00165 style,arsize1,colored,*arfact,typeofchamp));
00166
00167 sciDrawObjIfRequired( sciGetCurrentObj() ) ;
00168 DrawAxesIfRequired( sciGetCurrentObj() ) ;
00169
00170 if( style != NULL )
00171 {
00172 FREE( style ) ;
00173 style = NULL;
00174 }
00175
00176 }
00177
00178 int C2F(champ)(double *x, double *y, double *fx, double *fy, integer *n1, integer *n2, char *strflag, double *brect, double *arfact, integer lstr)
00179 {
00180 champg("champ",0,x,y,fx,fy,n1,n2,strflag,brect,arfact,lstr);
00181 return(0);
00182 }
00183
00184 int C2F(champ1)(double *x, double *y, double *fx, double *fy, integer *n1, integer *n2, char *strflag, double *brect, double *arfact, integer lstr)
00185 {
00186 champg("champ1",1,x,y,fx,fy,n1,n2,strflag,brect,arfact,lstr);
00187 return(0);
00188 }
00189
00190
00191
00192
00193
00194
00195
00196 static double MiniD(double *x, integer n)
00197 {
00198 int i;
00199 double dx=1,mindx=1;
00200 if ( n < 2 ) return(mindx);
00201 mindx= Abs(x[1]-x[0]);
00202 mindx = ( mindx != 0 ) ? mindx : 1;
00203 for ( i = 2 ; i < n ; i++)
00204 {
00205 dx = Abs(x[i]-x[i-1]);
00206 if ( dx < mindx && dx != 0 ) mindx=dx;
00207 }
00208 return(mindx);
00209 }
00210
00211
00212
00213
00214
00215
00216 void sciChamp2DRealToPixel( integer * xm ,
00217 integer * ym ,
00218 integer * zm ,
00219 integer * na ,
00220 integer * arsize ,
00221 double * x ,
00222 double * y ,
00223 double * fx ,
00224 double * fy ,
00225 integer * n1 ,
00226 integer * n2 ,
00227 double * arfact ,
00228 int * typeofchamp,
00229 BOOL clipping )
00230 {
00231
00232 integer i,j;
00233 double maxx;
00234 double nx,ny,sc,sfx,sfy,sfx2,sfy2;
00235 double arsize1=0.5,arsize2=0.5;
00236
00237 integer verbose=0,narg;
00238 int xfacteur = 1;
00239 int yfacteur = 1;
00240
00241 sciPointObj * psubwin = sciGetCurrentSubWin();
00242 sciSubWindow * ppsubwin = pSUBWIN_FEATURE (psubwin);
00243
00244 if ( ppsubwin->axes.reverse[0] ) { xfacteur = -1 ; }
00245 if ( ppsubwin->axes.reverse[1] ) { yfacteur = -1 ; }
00246
00247
00248 for ( i = 0 ; i < *n1 ; i++)
00249 {
00250 for ( j =0 ; j < *n2 ; j++)
00251 {
00252 xm[2*(i +(*n1)*j)]= XScale(x[i]);
00253 ym[2*(i +(*n1)*j)]= YScale(y[j]);
00254 }
00255 }
00256
00258 nx=MiniD(x,*n1)*Cscale.Wscx1;
00259 ny=MiniD(y,*n2)*Cscale.Wscy1;
00260 sfx= Cscale.Wscx1;
00261 sfy= Cscale.Wscy1;
00262 sfx2= sfx*sfx;
00263 sfy2= sfy*sfy;
00264 maxx = getLongestVector( fx, fy, *n1, *n2, sfx, sfy ) ;
00265 sc=maxx;
00266 sc= sqrt(nx*nx+ny*ny)/sc;
00267 sfx *= sc;
00268 sfy *= sc;
00270 arsize1= ((double) Cscale.WIRect1[2])/(5*(*n1));
00271 arsize2= ((double) Cscale.WIRect1[3])/(5*(*n2));
00272 *arsize= (arsize1 < arsize2) ? inint(arsize1*10.0) : inint(arsize2*10.0) ;
00273 *arsize = (int)((*arsize)*(*arfact));
00274
00275 set_clip_box(Cscale.WIRect1[0],Cscale.WIRect1[0]+Cscale.WIRect1[2],Cscale.WIRect1[1],
00276 Cscale.WIRect1[1]+Cscale.WIRect1[3]);
00277
00278 if ( *typeofchamp == 0 )
00279 {
00280 int j2=0;
00281 for ( i = 0 ; i < (*n1)*(*n2) ; i++)
00282 {
00283 integer x1n,y1n,x2n,y2n,flag1=0;
00284 xm[1+2*j2]= (int)(xfacteur*sfx*fx[i]+xm[2*i]);
00285 xm[2*j2] = (int)(xm[2*i]);
00286 ym[1+2*j2]= (int)(-yfacteur*sfy*fy[i]+ym[2*i]);
00287 ym[2*j2] = (int)(ym[2*i]);
00288 clip_line(xm[2*j2],ym[2*j2],xm[2*j2+1],ym[2*j2+1],&x1n,&y1n,&x2n,&y2n,&flag1);
00289 if ( flag1 != 0 )
00290 {
00291 if (flag1==1||flag1==3)
00292 {
00293 xm[2*j2] = x1n ;
00294 ym[2*j2] = y1n ;
00295 }
00296 if (flag1==2||flag1==3)
00297 {
00298 xm[2*j2+1] = x2n ;
00299 ym[2*j2+1] = y2n ;
00300 }
00301 j2++;
00302 }
00303 else if ( !clipping )
00304 {
00305 j2++ ;
00306 }
00307 }
00308 *na=2*j2;
00309 }
00310 else
00311 {
00312 integer x1n,y1n,x2n,y2n,flag1=0;
00313 integer whiteid;
00314 int j2=0;
00315 C2F(dr)("xget","lastpattern",&verbose,&whiteid,&narg,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
00316 for ( i = 0 ; i < (*n1)*(*n2) ; i++)
00317 {
00318 double nor= sqrt(sfx2*fx[i]*fx[i]+sfy2*fy[i]*fy[i]);
00319 zm[j2] = inint( ((double) whiteid -1 )*(1.0 - nor/maxx)) +1;
00320 nor= sqrt(fx[i]*(fx[i])+fy[i]*(fy[i]));
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 xm[1+2*j2]= (int)(xfacteur*sfx*(fx[i])/(nor)+xm[2*i]);
00336 xm[2*j2] = (int)(xm[2*i]);
00337 ym[1+2*j2]= (int)(-yfacteur*sfy*(fy[i])/(nor)+ym[2*i]);
00338 ym[2*j2] = (int)(ym[2*i]);
00339
00340
00341 clip_line(xm[2*j2],ym[2*j2],xm[2*j2+1],ym[2*j2+1],&x1n,&y1n,&x2n,&y2n,&flag1);
00342 if ( flag1 != 0 )
00343 {
00344 if (flag1==1||flag1==3)
00345 {
00346 xm[2*j2] = x1n ;
00347 ym[2*j2] = y1n ;
00348 }
00349 if (flag1==2||flag1==3)
00350 {
00351 xm[2*j2+1] = x2n ;
00352 ym[2*j2+1] = y2n ;
00353 }
00354 j2++;
00355 }
00356 else if ( !clipping )
00357 {
00358 j2++ ;
00359 }
00360 }
00361 *na=2*j2;
00362 }
00363 }
00364
00365
00380 void getChampDataBounds( double xCoords[] ,
00381 double yCoords[] ,
00382 double xLength[] ,
00383 double yLength[] ,
00384 int nbRow ,
00385 int nbCol ,
00386 int typeOfChamp,
00387 double * xMin ,
00388 double * xMax ,
00389 double * yMin ,
00390 double * yMax )
00391 {
00392 int i ;
00393 int * xPixCoords = NULL ;
00394 int * yPixCoords = NULL ;
00395 int * zPixCoords = NULL ;
00396 int nbArrowEnds = 2 * nbRow * nbCol ;
00397 int nbArrows ;
00398 int arrowSize = 0 ;
00399 double arrowSizeFact = 0.0 ;
00400
00401
00402 if ( nbArrowEnds == 0 )
00403 {
00404 *xMin = 0.0 ;
00405 *xMax = 0.0 ;
00406 *yMin = 0.0 ;
00407 *yMax = 0.0 ;
00408 return ;
00409 }
00410
00411 xPixCoords = MALLOC( nbArrowEnds * sizeof(int) ) ;
00412 yPixCoords = MALLOC( nbArrowEnds * sizeof(int) ) ;
00413 zPixCoords = MALLOC( nbRow * nbCol * sizeof(int) ) ;
00414
00415 if ( xPixCoords == NULL || yPixCoords == NULL || zPixCoords == NULL )
00416 {
00417 FREE( xPixCoords ) ;
00418 FREE( yPixCoords ) ;
00419 FREE( zPixCoords ) ;
00420 sciprint( "Cannot allocate temporary vector, memory full.\n" ) ;
00421 *xMin = 0.0 ;
00422 *xMax = 0.0 ;
00423 *yMin = 0.0 ;
00424 *yMax = 0.0 ;
00425 return ;
00426 }
00427
00428
00429 sciChamp2DRealToPixel( xPixCoords ,
00430 yPixCoords ,
00431 zPixCoords ,
00432 &nbArrows ,
00433 &arrowSize ,
00434 xCoords ,
00435 yCoords ,
00436 xLength ,
00437 yLength ,
00438 &nbRow ,
00439 &nbCol ,
00440 &arrowSizeFact,
00441 &typeOfChamp ,
00442 FALSE ) ;
00443
00444
00445
00446
00447 *xMin = XPixel2Double( xPixCoords[0] ) ;
00448 *xMax = *xMin ;
00449
00450 *yMin = YPixel2Double( yPixCoords[0] ) ;
00451 *yMax = *yMin ;
00452
00453 for ( i = 1 ; i < nbArrows ; i++ )
00454 {
00455 double currentCoordX = XPixel2Double( xPixCoords[i] ) ;
00456 double currentCoordY = YPixel2Double( yPixCoords[i] ) ;
00457
00458 *xMin = Min( *xMin, currentCoordX ) ;
00459 *xMax = Max( *xMax, currentCoordX ) ;
00460
00461 *yMin = Min( *yMin, currentCoordY ) ;
00462 *yMax = Max( *yMax, currentCoordY ) ;
00463 }
00464
00465 FREE( xPixCoords ) ;
00466 FREE( yPixCoords ) ;
00467 FREE( zPixCoords ) ;
00468
00469 }
00470
00471 double computeGridMinGap( double gridX[], double gridY[], int nbRow, int nbCol )
00472 {
00473 int i ;
00474 double min = 0 ;
00475 double minX = Abs( gridX[1] - gridX[0] ) ;
00476 double minY = Abs( gridY[1] - gridY[0] ) ;
00477
00478 for ( i = 1 ; i < nbRow-1 ; i++ )
00479 {
00480 double tmp = Abs( gridX[i+1] - gridX[i] ) ;
00481 if ( tmp < minX )
00482 {
00483 minX = tmp ;
00484 }
00485 }
00486
00487 for ( i = 1 ; i < nbCol-1 ; i++ )
00488 {
00489 double tmp = Abs( gridY[i+1] - gridY[i] ) ;
00490 if ( tmp < minY )
00491 {
00492 minY = tmp ;
00493 }
00494 }
00495
00496
00497 min = minX * minX + minY * minY ;
00498 min = ( min < SMDOUBLE) ? SMDOUBLE : sqrt(min) ;
00499
00500 return min ;
00501 }
00502
00503 int computeArrowColor( double gridX[], double gridY[], int nbRow, int nbCol, int index )
00504 {
00505 integer whiteid;
00506 int verbose = 0 ;
00507 int narg = 0 ;
00508 int j2=0 ;
00509 int color = 0 ;
00510 double scx = Cscale.Wscx1 ;
00511 double scy = Cscale.Wscy1 ;
00512
00513 double nor = sqrt( scx*scx*gridX[index]*gridX[index] + scy*scy*gridY[index]*gridY[index] ) ;
00514 double max = getLongestVector( gridX, gridY, nbRow, nbCol, scx, scy ) ;
00515
00516 C2F(dr)("xget","lastpattern",&verbose,&whiteid,&narg,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
00517
00518
00519 color = inint( (whiteid-1) * (1.0-nor/max) ) + 1 ;
00520
00521 return color ;
00522 }
00523
00524 double getLongestVector( double vectX[], double vectY[], int nbRow, int nbCol, double scx, double scy )
00525 {
00526 int i ;
00527
00528 double scx2 = scx * scx ;
00529 double scy2 = scy * scy ;
00530 double max = ( scx2 * vectX[0] * vectX[0] ) + ( scy2 * vectY[0] * vectY[0] ) ;
00531
00532 for ( i = 1 ; i < nbRow * nbCol ; i++ )
00533 {
00534 double tmp = ( scx2 * vectX[i] * vectX[i] ) + ( scy2 * vectY[i] * vectY[i] ) ;
00535 if ( tmp > max ) { max = tmp ; }
00536 }
00537 max = ( max < SMDOUBLE) ? SMDOUBLE : sqrt(max) ;
00538
00539 return max ;
00540 }
00541