FeC.c

Go to the documentation of this file.
00001 /*------------------------------------------------------------------------
00002  *    Graphic library
00003  *    Copyright (C) 1998-2001 Enpc
00004  *    Copyright INRIA 2006
00005  *    Jean-Philippe Chancelier - jpc@cermics.enpc.fr
00006  *    Jean-Baptiste Silvy
00007  *
00008  *    modified by Bruno Pincon 01/02/2001 for gain in speed and added 
00009  *    possibilities to set zmin, zmax by the user and also to set the 
00010  *    first and last color of the colormap (Bruno.Pincon@iecn.u-nancy.fr
00011  *
00012 for entities handling
00013  --------------------------------------------------------------------------*/
00014 
00015 #include <stdio.h>
00016 #include <math.h>
00017 #include <string.h>
00018 #include "math_graphics.h" 
00019 #include "Axes.h"
00020 
00021 #include "GetProperty.h"
00022 #include "SetProperty.h"
00023 #include "BuildObjects.h"
00024 #include "DrawObjects.h"
00025 #include "Xcall1.h"
00026 #include "MALLOC.h"
00027 #include "sciprint.h"
00028 #include "clipping.h"
00029 #include "CurrentObjectsManagement.h"
00030 
00031 
00032 /* functions used by the modified version : */
00033 static void PaintTriangle __PARAMS((double sx[], double sy[], double fxy[], 
00034                                     int zxy[], 
00035                                     double zlevel[], int fill[], BOOL with_mesh));
00036 static void PermutOfSort __PARAMS((int tab[], int perm[]));
00037 static void FindIntersection __PARAMS((double sx[], double sy[], double fxy[],
00038                                        double z, int inda, int indb, 
00039                                        integer *xint, integer *yint));
00040 void newfec __PARAMS((integer *xm,integer *ym,double *triangles,double *func,integer *Nnode,
00041                       integer *Ntr,double *zminmax,integer *colminmax, integer *colout, BOOL with_mesh));
00042 extern void initsubwin();
00043 /*extern void compute_data_bounds(int cflag,char dataflag,double *x,double *y,int n1,int n2,double *drect);*/
00044 extern void compute_data_bounds2(int cflag,char dataflag,char *logflags,double *x,double *y,int n1,int n2,double *drect);
00045 extern BOOL update_specification_bounds(sciPointObj *psubwin, double *rect,int flag);
00046 extern int re_index_brect(double * brect, double * drect);
00047 extern BOOL strflag2axes_properties(sciPointObj * psubwin, char * strflag);
00048 extern int CreatePrettyGradsFromNax(sciPointObj * psubwin,int * Nax);
00049 
00050 void get_frame_in_pixel(integer WIRect[]);
00051 
00052 /*------------------------------------------------------------
00053  *  Iso contour with grey level or colors 
00054  *  for a function defined by finite elements 
00055  *  ( f is linear on triangles )
00056  *  we give two versions of the function : 
00057  *     - a quick version wich only fill triangles according to the average 
00058  *     value of f on a triangle (no more such version now ?)
00059  *     - and a slow version but more sexy which use the fact that f is linear
00060  *     on each triangle.
00061  *  Nodes (x[no],y[no])
00062  *  Triangles (Matrix: [ numero, no1,no2,no3,iflag;...]
00063  *  func[no] : Function value on Nodes.
00064  *  Nnode : number of nodes 
00065  *  Ntr   : number of triangles 
00066  *  strflag,legend,brect,aint : see plot2d
00067  *  zminmax   : to set (optionnaly) the min and max level
00068  *  colminmax : to set (optionnaly) the first and last color to use
00069  *
00070  *  modified by Bruno Pincon 01/02/2001 for gain in speed and added 
00071  *  possibilities to set zmin, zmax by the user and also to set the 
00072  *  first and last color of the colormap (Bruno.Pincon@iecn.u-nancy.fr)
00073 ---------------------------------------------------------------*/
00074 
00075 int C2F(fec)(double *x, double *y, double *triangles, double *func, integer *Nnode, integer *Ntr, 
00076              char *strflag, char *legend, double *brect, integer *aaint, double *zminmax, 
00077              integer *colminmax, integer *colout, BOOL with_mesh, BOOL flagNax, integer lstr1, integer lstr2)
00078 {
00079   integer n1=1;
00080   
00081   /* Fec code */
00082   
00083 
00084   long hdltab[2];
00085   int cmpt=0,styl[2];
00086   sciPointObj *pptabofpointobj;
00087   sciPointObj  *psubwin;
00088   double drect[6];
00089 
00090   BOOL bounds_changed = FALSE;
00091   BOOL axes_properties_changed = FALSE;
00092 
00093 
00094   psubwin = sciGetCurrentSubWin();
00095 
00096   checkRedrawing() ;
00097 
00098 
00099 
00100   /* Force psubwin->is3d to FALSE: we are in 2D mode */
00101   if (sciGetSurface(psubwin) == (sciPointObj *) NULL)
00102   {
00103     pSUBWIN_FEATURE (psubwin)->is3d = FALSE;
00104     pSUBWIN_FEATURE (psubwin)->project[2]= 0;
00105   }
00106   else
00107   {
00108     pSUBWIN_FEATURE (psubwin)->theta_kp=pSUBWIN_FEATURE (psubwin)->theta;
00109     pSUBWIN_FEATURE (psubwin)->alpha_kp=pSUBWIN_FEATURE (psubwin)->alpha;  
00110   }
00111 
00112   pSUBWIN_FEATURE (psubwin)->alpha  = 0.0;
00113   pSUBWIN_FEATURE (psubwin)->theta  = 270.0;
00114 
00115   /* Force psubwin->axes.aaint to those given by argument aaint*/
00116   /*****TO CHANGE F.Leray 10.09.04     for (i=0;i<4;i++) pSUBWIN_FEATURE(psubwin)->axes.aaint[i] = aaint[i]; */
00117 
00118   /* Force "cligrf" clipping */
00119   sciSetIsClipping (psubwin,0); 
00120 
00121   /* Force  axes_visible property */
00122   /* pSUBWIN_FEATURE (psubwin)->isaxes  = TRUE;*/
00123 
00124   if (sciGetGraphicMode (psubwin)->autoscaling) {
00125     /* compute and merge new specified bounds with psubwin->Srect */
00126     switch (strflag[1])  {
00127       case '0': 
00128         /* do not change psubwin->Srect */
00129         break;
00130       case '1' : case '3' : case '5' : case '7':
00131         /* Force psubwin->Srect=brect */
00132         re_index_brect(brect, drect);
00133         break;
00134       case '2' : case '4' : case '6' : case '8':case '9':
00135         /* Force psubwin->Srect to the x and y bounds */
00136         /* compute_data_bounds(0,'g',x,y,n1,*Nnode,drect); */
00137         compute_data_bounds2(0,'g',pSUBWIN_FEATURE(psubwin)->logflags,x,y,n1,*Nnode,drect);
00138         break;
00139     }
00140     if (!pSUBWIN_FEATURE(psubwin)->FirstPlot &&
00141       (strflag[1] == '7' || strflag[1] == '8' || strflag[1] == '9')) { /* merge psubwin->Srect and drect */
00142         drect[0] = Min(pSUBWIN_FEATURE(psubwin)->SRect[0],drect[0]); /*xmin*/
00143         drect[2] = Min(pSUBWIN_FEATURE(psubwin)->SRect[2],drect[2]); /*ymin*/
00144         drect[1] = Max(pSUBWIN_FEATURE(psubwin)->SRect[1],drect[1]); /*xmax*/
00145         drect[3] = Max(pSUBWIN_FEATURE(psubwin)->SRect[3],drect[3]); /*ymax*/
00146     }
00147     if (strflag[1] != '0') 
00148       bounds_changed = update_specification_bounds(psubwin, drect,2);
00149   } 
00150 
00151   if(pSUBWIN_FEATURE (psubwin)->FirstPlot == TRUE) bounds_changed = TRUE;
00152 
00153   axes_properties_changed = strflag2axes_properties(psubwin, strflag);
00154 
00155   pSUBWIN_FEATURE (psubwin)->FirstPlot = FALSE; /* just after strflag2axes_properties */
00156 
00157   /* F.Leray 07.10.04 : trigger algo to init. manual graduation u_xgrads and 
00158   u_ygrads if nax (in matdes.c which is == aaint HERE) was specified */
00159 
00160   pSUBWIN_FEATURE(psubwin)->flagNax = flagNax; /* store new value for flagNax */
00161 
00162   if(pSUBWIN_FEATURE(psubwin)->flagNax == TRUE){
00163     if(pSUBWIN_FEATURE(psubwin)->logflags[0] == 'n' && pSUBWIN_FEATURE(psubwin)->logflags[1] == 'n')
00164     {
00165       pSUBWIN_FEATURE(psubwin)->axes.auto_ticks[0] = FALSE; /* x and y graduations are imposed by Nax */
00166       pSUBWIN_FEATURE(psubwin)->axes.auto_ticks[1] = FALSE;
00167 
00168       CreatePrettyGradsFromNax(psubwin,aaint);
00169     }
00170     else{
00171       sciprint("Warning : Nax does not work with logarithmic scaling\n");}
00172   }
00173 
00174   if(bounds_changed == TRUE || axes_properties_changed == TRUE)
00175   {
00176     sciDrawObj(sciGetCurrentFigure());
00177   }
00178   /*      EraseAndOrRedraw(psubwin);  /\*  inhibit EraseAndOrRedraw for now F.Leray 20.12.04 *\/ */
00179 
00180   sciSetCurrentObj (ConstructFec 
00181     ((sciPointObj *)
00182     sciGetCurrentSubWin(),
00183     x,y,triangles,func,*Nnode,*Ntr,zminmax,colminmax,colout, with_mesh)); 
00184 
00185   /* retrieve the created object : fec */
00186   pptabofpointobj = sciGetCurrentObj();
00187   hdltab[cmpt]=sciGetHandle(pptabofpointobj);   
00188   cmpt++;   
00189   sciDrawObjIfRequired(sciGetCurrentObj ());
00190   DrawAxesIfRequired(sciGetCurrentObj ()); /* force axes redrawing */
00192   if ((int)strlen(strflag) >=1  && strflag[0] == '1')
00193   {
00194     n1=1; styl[0]=1;styl[1]=0;
00195     sciSetCurrentObj (ConstructLegend
00196       (sciGetCurrentSubWin(),
00197       legend, strlen(legend), n1, styl, &pptabofpointobj)); 
00198 
00199     /*       sciSetMarkSizeUnit(sciGetCurrentObj(),2); /\* force switch to tabulated mode : old syntax *\/ */
00200 
00201     /* removed JB Silvy 12/05 */
00202     /* fec object has no mark properties */
00203     /*sciSetIsMark(pptabofpointobj, TRUE);*/
00204     /*sciSetMarkStyle (pptabofpointobj, *styl);*/
00205 
00206 
00207     sciDrawObjIfRequired(sciGetCurrentObj ()); 
00208     DrawAxesIfRequired(sciGetCurrentObj ()); /* force axes redrawing */
00209     hdltab[cmpt]=sciGetHandle(sciGetCurrentObj ()); 
00210     cmpt++;
00211   }
00212   sciSetCurrentObj(ConstructCompound (hdltab, cmpt));  
00215   return(0);
00216    
00217 }
00218 
00219 void newfec(integer *xm,integer *ym,double *triangles,double *func,integer *Nnode,
00220             integer *Ntr,double *zminmax,integer *colminmax, integer *colout, BOOL with_mesh)
00221 {
00222   /*   code modified by Bruno 01/02/2001
00223    *   a new modif (Bruno 04 nov 2004 from an idea of Jpc): adding the 
00224    *   colout to choose the colors when the zminmax levels are 
00225    *   crossed (and the color 0 correspond to no painting at all these zones)
00226    *   a new modif (Bruno 08 nov 2004 from an idea of Jpc): adding with_mesh to see or not the mesh  
00227    */
00228     
00229   integer nz,i,j,k;
00230   integer verbose=0,whiteid,narg;
00231     
00232   double *zlevel, dz, zmin, zmax, fxy[3], sx[3], sy[3];
00233   int *zone, *fill, kp, perm[3], zxy[3], color_min, color_max, col_under_min, col_upper_max;
00234   integer ii[3];
00235 
00236   /* pour le pre-cliping */
00237   integer WIRect[4];
00238   double Fxmin, Fxmax, Fymin, Fymax;
00239 
00240   frame_clip_on();
00241 
00242   /*   choice between zmin and zmax given by the user or computed
00243    *   with the min and max z values. In matdes.c I have put 
00244    *   zminmax[0]= zminmax[1]=0 if the user don't give this argument 
00245    */
00246   if ( zminmax[0]==zminmax[1] ) 
00247     {  
00248       zmin=(double) Mini(func,*Nnode); zmax=(double) Maxi(func,*Nnode);
00249     } 
00250   else 
00251     {
00252       zmin = Min( zminmax[0] , zminmax[1] ); zmax = Max( zminmax[0] , zminmax[1] );
00253     };
00254   
00255 
00256   /*   choice for the colormap (in case of a user 's choice 
00257    *   verify the parameter). For the automatic choice I have
00258    *   put colminmax[0]=colominmax[1]=1 in matdes.c  
00259    */
00260   C2F(dr)("xget","lastpattern",&verbose,&whiteid,&narg,
00261           PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
00262   nz=whiteid;
00263   if ( colminmax[0] == 0  &&  colminmax[1] == 0 )  /* automatic choice (see matdes.c) */
00264     {
00265       color_min = 1; 
00266       color_max = nz;
00267     }
00268   else if ( colminmax[0] < 1 || colminmax[1] > nz || colminmax[0] > colminmax[1] ) 
00269     {
00270       sciprint("\n\r fec : colminmax badly choosen ! "); 
00271       return;
00272     } 
00273   else 
00274     {
00275       color_min = colminmax[0]; 
00276       color_max = colminmax[1];
00277     };
00278 
00279   /*   choice for the "out" colors (for the automatic choice I have
00280    *   put colout[0]= colout[1]=-1 in matdes.c)  
00281    */
00282   if ( colout[0] < -1 || colout[0] > nz || colout[1] < -1 || colout[1] > nz )
00283     {
00284       sciprint("\n\r fec : colout badly choosen ! "); return;
00285     } 
00286 
00287   if ( colout[0] == -1 )  /* automatic choice */
00288     col_under_min = color_min;
00289   else
00290     col_under_min =  colout[0];
00291 
00292   if ( colout[1] == -1 )  /* automatic choice */
00293     col_upper_max = color_max;
00294   else
00295     col_upper_max =  colout[1];
00296 
00297   /* 
00298    *  1/ the purpose of the first part is to to compute the "zone" of each point :
00299    *    
00300    *    - the array zlevel are the boundaries between the differents zones :
00301    *
00302    *        zlevel[0] = zmin, zlevel[nz] = zmax 
00303    *     and zlevel[i] = zmin + i*(zmax-zmin)/nz
00304    *  
00305    *     - if  zlevel[j-1] <= func[i] < zlevel[j]  then zone[i] = j
00306    *       if func[i] > zmax  then zone[i] = nz+1
00307    *       if func[i] < zmin  then zone[i] = 0
00308    *     - the zone j is filled with color fill[j] with
00309    *       fill[j] = -(j-1 + color_min) if 1 <= j <= nz
00310    *       fill[0] = color attributed for fill[1]     ---> this behavior may be changed ...
00311    *       fill[nz+1] = color attributed for fill[nz] --/
00312    */
00313  
00314   /* allocations for some arrays ... */
00315   nz = color_max - color_min + 1;
00316   zone   = MALLOC( *Nnode * sizeof(int)    ) ;
00317   zlevel = MALLOC( (nz+1) * sizeof(double) ) ;
00318   fill   = MALLOC( (nz+2) * sizeof(int)    ) ;
00319   if ( (zone == NULL) || (zlevel == NULL) || (fill  == NULL)) 
00320   {
00321     sciprint("fec: malloc No more Place\n");
00322     return;
00323   }
00324 
00325   /* compute the fill array (fill = - num color) */
00326   fill[0] = -col_under_min;
00327   fill[1] = -color_min;
00328   for ( i = 2 ; i <= nz ; i++ ) fill[i] = fill[i-1] - 1;
00329   fill[nz+1] = -col_upper_max;
00330 
00331   /* compute the zlevels */
00332   dz = (zmax - zmin)/nz;
00333   for (i = 0 ; i < nz ; i++) zlevel[i] = zmin + i*dz;
00334   zlevel[nz] = zmax;
00335 
00336   /* finaly compute the zone of each point */
00337   for ( i = 0 ; i < (*Nnode) ; i++ ) 
00338     {
00339       if ( func[i] > zmax )
00340         zone[i] = nz+1;
00341       else if ( func[i] < zmin )
00342         zone[i] = 0;
00343       else
00344         zone[i] = (int) (floor( (func[i] - zmin)/dz ) + 1);
00345     };
00346 
00347   /* 
00348    *  2/ loop of the triangles : each triangle is finally decomposed 
00349    *  into its differents zones (polygons) by the function PaintTriangle   
00350    */
00351 
00352   get_frame_in_pixel(WIRect);
00353   Fxmin = (double) WIRect[0];  Fymin = (double) WIRect[1];
00354   Fxmax = (double) WIRect[2];  Fymax = (double) WIRect[3];
00355 
00356   for ( j = 0 ; j < *Ntr ; j++) 
00357     {
00358       double xmin, xmax, ymin, ymax;
00359       /* retrieve node numbers and functions values */
00360       for ( k = 0 ; k < 3 ; k++ ) 
00361         {
00362           ii[k] = (integer) triangles[j+(*Ntr)*(k+1)] - 1;      
00363           zxy[k] = zone[ii[k]];  
00364         }
00365 
00366       /* get the permutation perm so as zxy[perm] is sorted */
00367       PermutOfSort(zxy, perm); 
00368 
00369       /* apply the permutation to get the triangle 's vertices
00370          in increasing zone (zxy[0] <= zxy[1] <= zxy[2]) */
00371       for ( k = 0 ; k < 3 ; k++ ) 
00372         {
00373           kp = perm[k];
00374           sx[k]  = xm[ii[kp]];   sy[k]  = ym[ii[kp]];
00375           fxy[k] = func[ii[kp]]; zxy[k] = zone[ii[kp]];
00376         };
00377 
00378       /* essai de pre-clipping tous les triangles en dehors de la zone
00379          d'affichage ne seront pas traités */
00380       xmin = xmax = sx[0]; ymin = ymax = sy[0];
00381       if ( sx[1] < sx[2] ) 
00382         { 
00383           xmin = Min(xmin,sx[1]); xmax = Max(xmax,sx[2]);
00384         } 
00385       else 
00386         {
00387           xmin = Min(xmin,sx[2]); xmax = Max(xmax,sx[1]);
00388         }
00389       if ( sy[1] < sy[2] )
00390         { 
00391           ymin = Min(ymin,sy[1]); ymax = Max(ymax,sy[2]);
00392         }
00393       else
00394         {
00395           ymin = Min(ymin,sy[2]); ymax = Max(ymax,sy[1]);
00396         }
00397       
00398       if ( xmax > Fxmin  &&  ymax > Fymin  &&  xmin < Fxmax  &&  ymin < Fymax )
00399       { 
00400         /* call the "painting" function */
00401         PaintTriangle(sx, sy, fxy, zxy, zlevel, fill, with_mesh);
00402       }
00403     }
00404 
00405   FREE( zone   ) ;
00406   FREE( zlevel ) ;
00407   FREE( fill   ) ;
00408 
00409 
00410   frame_clip_off();
00411 }
00412 
00413 
00414 /********************************************************************
00415  * functions used by the modified code (Bruno 01/02/2001)
00416  ********************************************************************/
00417 
00418 static void PermutOfSort (int *tab, int *perm)
00419 {
00420   /* 
00421    * get the permutation perm[3] which sort the array tab[3] in increasing order 
00422    */
00423   perm[0]=0; perm[1] = 1; perm[2] = 2;
00424   if ( tab[1] < tab[0] ) 
00425     {
00426       perm[1]=0 ; perm[0] = 1;
00427     };
00428   if ( tab[2] < tab[perm[1]] ) 
00429     {   /* sort not finish */
00430       if ( tab[2] < tab[perm[0]] ) 
00431         {
00432           perm[2] = perm[1]; perm[1] = perm[0]; perm[0] = 2; 
00433         }
00434       else 
00435         {
00436           perm[2] = perm[1] ; perm[1] = 2;
00437         };
00438     };
00439 }
00440 
00441 static void PaintTriangle (double *sx, double *sy, double *fxy, int *zxy, 
00442                            double *zlevel, int *fill, BOOL with_mesh)
00443 {
00444   /* 
00445      arguments :
00446      ---------
00447      sx, sy : vertices coordinates of a triangle (Pi=(sx[i],sy[i]) i=0,1,2)
00448      fxy    : fxy[i], (i=0,1,2) value of an affine function on the vertex Pi
00449      zxy    : zone of Pi : zxy[i]=j if  zlevel[j-1] <= fxy[i] < zlevel[j]
00450      zlevel : a (0..nz) vector given the boundaries for color filling
00451      fill   : fill[j] is the color pattern associated with zone[j] 
00452      
00453      purpose : this function decompose the triangle into its different
00454      -------   zones (which gives polygones) and send them to the
00455      graphic driver. This is something like the shade function
00456      (see Plo3d.c) but a little different as in shade
00457      a color is directly associated with each vertex.
00458   */
00459 
00460   int nb0, edge, izone, color;
00461   integer ncont,nr, zero=0, resx[5],resy[5];
00462   integer xEdge2, yEdge2, xEdge, yEdge; 
00463 
00464   if ( zxy[0] == zxy[2] )   /*  case of only one color for the triangle : */
00465     {
00466       resx[0]=inint(sx[0]); resx[1]=inint(sx[1]);  resx[2]=inint(sx[2]);
00467       resy[0]=inint(sy[0]); resy[1]=inint(sy[1]);  resy[2]=inint(sy[2]);
00468       color = fill[zxy[0]]; nr = 3;
00469       if ( color != 0 )
00470       {
00471         C2F(dr)("xliness","str",resx,resy,&color,(ncont=1,&ncont),&nr, 
00472                 PI0,PD0,PD0,PD0,PD0,0L,0L);
00473       }
00474       if ( with_mesh )
00475       {
00476         C2F(dr)("xliness","str",resx,resy,&zero,(ncont=1,&ncont),&nr, 
00477                 PI0,PD0,PD0,PD0,PD0,0L,0L);
00478       }
00479       return;
00480     }
00481 
00482   /* 
00483      at least 2 colors for painting the triangle : it is divided in elementary
00484      polygons. The number of polygons is npolys = zxy[2]-zxy[0]+1.
00485 
00486      P2           as zxy[0] <= zxy[1] <  zxy[2] or 
00487      Notations/Hints :       /\              zxy[0] <  zxy[1] <= zxy[2]
00488      edge2  /  \ edge1    from a previus sort. All the polygons
00489      /    \         have 2 points on edge2, the others points
00490      /______\        are on edge0 and/or edge1. I name the 2 ends
00491      P0        P1      points on each poly PEdge2 and Pedge, they are 
00492      edge0         the 2 first points of the next poly. I start
00493      from P0 to form the first poly (a triangle or
00494      a 4 sides depending if zxy[0]=zxy[1]), then the 2, 3, .., npolys - 1 (if they exist)
00495      and finally the last one which comprise the P2 vertex.  In some special cases
00496      we can have a degenerate poly but it doesn't matter !                                
00497   */
00498   
00499   nb0 = zxy[1]-zxy[0]; /* number of intersection points on edge 0 */
00500 
00501   /*----------------------------+
00502     |   compute the first poly    |
00503     +----------------------------*/
00504   
00505   resx[0]=inint(sx[0]); resy[0]=inint(sy[0]); nr = 1; edge = 0;
00506   if ( nb0 == 0 )  /* the intersection point is on Edge1 but */
00507   {              /* the next point of the poly is P1 */  
00508     resx[1] = inint(sx[1]);
00509     resy[1] = inint(sy[1]);
00510     nr++;
00511     edge = 1;    /* the next intersection points will be on edge1 */
00512   } 
00513   else
00514   {
00515     nb0--;
00516   }
00517   /* the intersection point on edge (0 or 1) : */
00518   FindIntersection(sx, sy, fxy, zlevel[zxy[0]], edge, edge+1, &xEdge, &yEdge);
00519   resx[nr] = xEdge; 
00520   resy[nr] = yEdge; 
00521   nr++;
00522   /* the last point of the first poly (edge 2) : */
00523   FindIntersection(sx, sy, fxy, zlevel[zxy[0]], 0, 2, &xEdge2, &yEdge2);
00524   resx[nr] = xEdge2; 
00525   resy[nr] = yEdge2;
00526   nr++;
00527   color = fill[zxy[0]];
00528   if ( color != 0 )
00529   {
00530     C2F(dr)("xliness","str",resx,resy,&color,(ncont=1,&ncont),&nr, 
00531             PI0,PD0,PD0,PD0,PD0,0L,0L);
00532   }
00533 
00534   /*------------------------------------+ 
00535     | compute the intermediary polygon(s) |
00536     +------------------------------------*/
00537 
00538   for ( izone = zxy[0]+1 ; izone < zxy[2] ; izone++ ) 
00539   {
00540     resx[0] = xEdge2; 
00541     resy[0] = yEdge2;          /* the 2 first points are known */
00542     resx[1] = xEdge ;
00543     resy[1] = yEdge ; 
00544     nr      = 2     ;
00545     if ( edge == 0 )   /* the intersection point is perhaps on edge 0 */
00546     {
00547       if (nb0 == 0 )  /* no it is on edge 1 but the next point of the poly is P1 */
00548       {
00549         resx[2] = inint(sx[1]);
00550         resy[2] = inint(sy[1]);
00551         nr++;
00552         edge = 1;          /* the next intersection points will be on edge1 */
00553       }
00554       else
00555       {
00556         nb0--;
00557       }
00558     }
00559     /* the intersection point on edge (0 or 1) : */
00560     FindIntersection(sx, sy, fxy, zlevel[izone], edge, edge+1, &xEdge, &yEdge);
00561     resx[nr]=xEdge; resy[nr]=yEdge; nr++;
00562     /* the last point of the first poly (edge 2) : */
00563     FindIntersection(sx, sy, fxy, zlevel[izone], 0, 2, &xEdge2, &yEdge2);
00564     resx[nr]=xEdge2; resy[nr]=yEdge2; nr++;
00565     color = fill[izone];
00566     if ( color != 0 )
00567     {
00568       C2F(dr)("xliness","str",resx,resy,&color,(ncont=1,&ncont),&nr, 
00569               PI0,PD0,PD0,PD0,PD0,0L,0L);
00570     }
00571   }
00572 
00573   /*-----------------------+ 
00574     | compute the last poly  |
00575     +-----------------------*/
00576   resx[0] = xEdge2;
00577   resy[0] = yEdge2;         /* the 2 first points are known */
00578   resx[1] = xEdge;
00579   resy[1] = yEdge;
00580   nr = 2;
00581   if ( edge == 0 )  /* the next point of the poly is P1 */
00582   {                         
00583     resx[2]=inint(sx[1]);
00584     resy[2]=inint(sy[1]);
00585     nr++;
00586   } ;
00587   /* the last point is P2 */
00588   resx[nr] = inint(sx[2]);
00589   resy[nr] = inint(sy[2]);
00590   nr++;
00591   color = fill[zxy[2]];
00592   if ( color != 0 )
00593   {
00594     C2F(dr)("xliness","str",resx,resy,&color,(ncont=1,&ncont),&nr, 
00595             PI0,PD0,PD0,PD0,PD0,0L,0L);
00596   }
00597 
00598   if ( with_mesh )
00599     {
00600       resx[0]=inint(sx[0]); resx[1]=inint(sx[1]);  resx[2]=inint(sx[2]);
00601       resy[0]=inint(sy[0]); resy[1]=inint(sy[1]);  resy[2]=inint(sy[2]);
00602       nr = 3;
00603       C2F(dr)("xliness","str",resx,resy,&zero,(ncont=1,&ncont),&nr, 
00604               PI0,PD0,PD0,PD0,PD0,0L,0L);
00605     }
00606 }
00607 
00608 static void FindIntersection(double *sx, double *sy, double *fxy, double z, 
00609                              int inda, int indb, integer *xint, integer *yint)
00610 {
00611   double alpha;
00612   alpha = (z - fxy[inda])/(fxy[indb] - fxy[inda]);
00613   *xint = inint((1 - alpha)*sx[inda] + alpha*sx[indb]);
00614   *yint = inint((1 - alpha)*sy[inda] + alpha*sy[indb]);
00615 }
00616 
00617 
00618 
00619 
00620 
00621 
00622 
00623 
00624 
00625 

Generated on Sun Mar 4 15:03:51 2007 for Scilab [trunk] by  doxygen 1.5.1