DrawObjects.c

Go to the documentation of this file.
00001 /*------------------------------------------------------------------------
00002  *    Graphic library 
00003  *    Copyright INRIA
00004  *    newGraph Library header
00005  *    Matthieu PHILIPPE,   INRIA 2001-2002
00006  *    Djalel ABDEMOUCHE,   INRIA 2002-2004
00007  *    Fabrice Leray,       INRIA 2004-2006
00008  *    Jean-Baptiste Silvy, INRIA 2006-xxxxdrawmerge
00009  *    Comment:
00010  *    This file contains all functions used to Draw the content of a window.
00011  *    The main functions is sciDrawObj that draws the objects recursively.
00012  ------------------------------------------------------------------------/-*/
00013 #include <math.h>
00014 
00015 #include <stdio.h> 
00016 #include <string.h>
00017 #include <stdlib.h>
00018 #include <stdarg.h>
00019 #include <time.h>
00020 
00021 #include "DrawObjects.h"
00022 #include "GetProperty.h"
00023 #include "bcg.h"
00024 #include "SetProperty.h"
00025 #include "BuildObjects.h"
00026 #include "DestroyObjects.h"
00027 #include "ObjectStructure.h"
00028 #include "Axes.h"
00029 #include "Xcall1.h"
00030 #include "Champ.h"
00031 #include "StringBox.h"
00032 #include "handleDrawing/drawTextEntity.h"
00033 #include "handleDrawing/drawFigureEntity.h"
00034 #include "handleDrawing/drawSubWinEntity.h"
00035 #include "handleDrawing/drawCompoundEntity.h"
00036 #include "handleDrawing/drawLegendEntity.h"
00037 #include "handleDrawing/drawFecEntity.h"
00038 #include "handleDrawing/drawSegsEntity.h"
00039 #include "handleDrawing/drawGrayplotEntity.h"
00040 #include "handleDrawing/drawPolylineEntity.h"
00041 #include "handleDrawing/drawArcEntity.h"
00042 #include "handleDrawing/drawRectangleEntity.h"
00043 #include "handleDrawing/drawAxesEntity.h"
00044 #include "handleDrawing/drawMergeEntity.h"
00045 #include "handleDrawing/drawSurfaceEntity.h"
00046 #include "periScreen.h" /* to be removed */
00047 #include "PloEch.h"
00048 #include "axesScale.h"
00049 #include "sciprint.h"
00050 #include "CurrentObjectsManagement.h"
00051 
00052 #include "math_graphics.h"
00053 #include "graphicSession.h"
00054 #include "Format.h"
00055 #include "axesScale.h"
00056 #include "drawMarks.h"
00057 #include "BasicAlgos.h"
00058 
00059 #include "MALLOC.h" /* MALLOC */
00060 
00061 #ifdef WITH_TK
00062 #include "../../../tclsci/includes/GedManagement.h"
00063 #endif
00064 
00065 #ifdef _MSC_VER
00066 extern HDC TryToGetDC(HWND hWnd);
00067 #endif
00068 
00069 #define         round(a)        (int)(((a)<0.0)?(a)-.5:(a)+.5)
00070 
00071 extern double C2F(dsort)();/*DJ.A merge*/ 
00072 extern int scilab_shade(integer *polyx, integer *polyy, integer *fill, integer polysize, integer flag);
00073 
00074 void GradFixedlog( double minVal, double maxVal, double * ticks, int nbGrads );
00075 int sciGetLogExponent( double minBound, double maxBound, double * expMin, double * expMax );
00076 
00077 unsigned short defcolors[] = {
00078   0,   0,   0, /* Black: DEFAULTBLACK */
00079   0,   0, 255, /* Blue */
00080   0, 255,   0, /* Green */
00081   0, 255, 255, /* Cyan */
00082   255,   0,   0, /* Red */
00083   255,   0, 255, /* Magenta */
00084   255,   255,   0, /* Yellow */
00085   255, 255, 255, /* White: DEFAULTWHITE */
00086   0,   0, 144, /* Blue4 */
00087   0,   0, 176, /* Blue3 */
00088   0,   0, 208, /* Blue2 */
00089   135, 206, 255, /* LtBlue */
00090   0, 144,   0, /* Green4 */
00091   0, 176,   0, /* Green3 */
00092   0, 208,   0, /* Green2 */
00093   0, 144, 144, /* Cyan4 */
00094   0, 176, 176, /* Cyan3 */
00095   0, 208, 208, /* Cyan2 */
00096   144,   0,   0, /* Red4 */
00097   176,   0,   0, /* Red3 */
00098   208,   0,   0, /* Red2 */
00099   144,   0, 144, /* Magenta4 */
00100   176,   0, 176, /* Magenta3 */
00101   208,   0, 208, /* Magenta2 */
00102   128,  48,   0, /* Brown4 */
00103   160,  64,   0, /* Brown3 */
00104   192,  96,   0, /* Brown2 */
00105   255, 128, 128, /* Pink4 */
00106   255, 160, 160, /* Pink3 */
00107   255, 192, 192, /* Pink2 */
00108   255, 224, 224, /* Pink */
00109   255, 215,   0  /* Gold */
00110 };
00111 
00112 
00113 
00114 
00115 void sciRedrawFigure( void )
00116 {
00117   sciDrawObj (sciGetCurrentFigure ());
00118 }
00119 
00120 void sciRedrawF(value)
00121      int *value;   
00122 { 
00123   sciPointObj *figure; 
00124   integer cur,na,verb=0;
00125   figure= (sciPointObj *) sciIsExistingFigure(value); 
00126   /* F.Leray 13.04.04 : Test if returned sciPointObj* is NULL (means Figure has been destroyed) */
00127 
00128   if(figure == (sciPointObj *)  NULL)
00129     {
00130       /* Do nothing */
00131     }
00132   else
00133     {
00134       C2F (dr) ("xget", "window",&verb,&cur,&na,PI0,PI0,PI0,PD0,PD0,PD0,PD0,4L,6L);
00135       C2F (dr) ("xset", "window",value,PI0,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,4L,6L);
00136       sciDrawObj (figure);
00137       C2F (dr) ("xset", "window",&cur,PI0,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,4L,6L);
00138     }
00139 }
00140 
00141 void sciXbasc()
00142 {  
00143   static sciPointObj *mafigure;
00144   static sciPointObj *masousfen;  
00145  
00146   mafigure= (sciPointObj *) sciGetCurrentFigure(); 
00147   DestroyAllGraphicsSons((sciPointObj *)mafigure);
00148   
00149    
00150   if ((masousfen = ConstructSubWin (mafigure, 'o')) != NULL){
00151     sciSetCurrentObj(masousfen);
00152     sciSetOriginalSubWin (mafigure, masousfen);}
00153   sciDrawObj(sciGetCurrentFigure ());      
00154 }       
00155 
00156 void sciXclear()
00157 {
00158   static sciPointObj *masousfen, *tmpsousfen;
00159   sciSons *psonstmp; 
00160      
00161   tmpsousfen= sciGetCurrentSubWin();
00162   psonstmp = sciGetSons (sciGetCurrentFigure());
00163   
00164   while (psonstmp != (sciSons *) NULL)  
00165     {  
00166       if(sciGetEntityType (psonstmp->pointobj) == SCI_SUBWIN)
00167         {
00168           masousfen= (sciPointObj *)psonstmp->pointobj;
00169           sciSetSelectedSubWin (masousfen);
00170           sciSetdrawmode (FALSE); 
00171         }
00172       psonstmp = psonstmp->pnext;
00173     }
00174   sciSetSelectedSubWin (tmpsousfen);
00175   sciDrawObj(sciGetCurrentFigure ());      
00176 }
00177 
00178 /* update the scale and retrieve the bounding box of the axis */
00179 void updateScale3d( sciPointObj * pobj    ,
00180                     double        dbox[6] ,
00181                     double        xbox[8] ,
00182                     double        ybox[8] ,
00183                     double        zbox[8]  )
00184 {
00185   int    flag     ;
00186   int    i        ;
00187   double xmmin    ;
00188   double xmmax    ;
00189   double ymmin    ;
00190   double ymmax    ;
00191   double wmax     ;
00192   double hmax     ;
00193   integer aaint[] = {2,10,2,10} ;
00194   sciSubWindow * ppsubwin =  pSUBWIN_FEATURE (pobj);
00195 
00196   sci_update_frame_bounds_3d( pobj ) ;
00197        
00198   dbox[0] =  ppsubwin->FRect[0] ; /*xmin*/
00199   dbox[1] =  ppsubwin->FRect[2] ; /*xmax*/
00200   dbox[2] =  ppsubwin->FRect[1] ; /*ymin*/
00201   dbox[3] =  ppsubwin->FRect[3] ; /*ymax*/
00202   dbox[4] =  ppsubwin->FRect[4] ; /*zmin*/
00203   dbox[5] =  ppsubwin->FRect[5] ; /*zmax*/
00204 
00205   if( ppsubwin->cube_scaling )
00206   {
00207     dbox[0] =  0.; 
00208     dbox[1] =  1.;
00209     dbox[2] =  0.;
00210     dbox[3] =  1.;
00211     dbox[4] =  0.;
00212     dbox[5] =  1.;
00213   }
00214 
00215 
00217   flag = ( ppsubwin->axes.flag[1] + 1 ) / 2 ; /* F.Leray Adding HERE 19.04.04 */
00218 
00219   Cscale.alpha = ppsubwin->alpha ;
00220   Cscale.theta = ppsubwin->theta ;
00221       
00222   /* update Cscale.m from the new viewing angles */
00223   sciUpdateScaleAngles( ppsubwin->theta, ppsubwin->alpha ) ;
00224       
00225   for ( i = 0 ; i < 6 ; i++ ) 
00226   { 
00227     if ( flag == 0 )
00228     { 
00229       dbox[i] = Cscale.bbox1[i];
00230     }
00231     else
00232     { 
00233       Cscale.bbox1[i] = dbox[i];
00234     }
00235   }
00236 
00237   /* get the vertices of the axes box */
00238   sciGetAxisBox( dbox, xbox, ybox, zbox ) ;
00239       
00241   if ( flag == 1 || flag == 3 ) /* ALL the expanded cases : flag[1] = 1 or 2 or 5 or 6 */
00242   {
00243     xmmin =  Mini(xbox,8L) ;
00244     xmmax =  Maxi(xbox,8L) ; /* search for x Min/Max on all the edges (there are 8 edges that compose the box) F.Leray 13.10.04 */
00245     ymmax = -Mini(ybox,8L) ; /* same thing on ybox vector ( 1) why - (minus) ? see 2) )*/
00246     ymmin = -Maxi(ybox,8L);
00247   }
00248   
00249   if ( flag == 2 || flag == 3 ) /* ALL the isometric cases : flag[1] = 3 or 4 or 5 or 6 */
00250   {
00251     int verbose = 0 ;
00252     int narg        ;
00253     int wdim[2]     ;
00254     double FRect[4] ;
00255     double WRect[4] ;
00256     double ARect[4] ;
00257     char   logf_[2]  ;
00258     /* get current window size */
00259     C2F(dr)("xget","wdim",&verbose,wdim,&narg, PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
00260     getscale2d(WRect,FRect,logf_,ARect);
00261     wmax=linint((double)wdim[0] * WRect[2]);
00262     hmax=linint((double)wdim[1] * WRect[3]); 
00263   }
00264   
00265   if ( flag == 2 ) /* the "NON expanded isometric" cases : flag[1] = 3 or 4 */
00266   {
00267     double R  ;
00268     double xo ;
00269     double yo ;
00270     double zo ;
00271     double dx ;
00272     double dy ;
00273     double dz ;
00274     
00275     /* radius and center of the sphere circumscribing the box */
00276     dx = dbox[1] - dbox[0] ;
00277     dy = dbox[3] - dbox[2] ;
00278     dz = dbox[5] - dbox[4] ;
00279     
00280     R  = sqrt( dx*dx + dy*dy + dz*dz)/2;
00281     xo = ( xbox[0] + xbox[6] ) / 2.0 ;
00282     yo = ( ybox[0] + ybox[6] ) / 2.0 ;
00283     zo = ( zbox[0] + zbox[6] ) / 2.0 ;
00284     
00285     xmmin=   xo - R ;
00286     xmmax=   xo + R ;
00287     ymmax=  -yo + R ;
00288     ymmin=  -yo - R ;
00289   }
00290 
00291   if (flag==2 || flag==3)
00292   {
00293     double hx ;
00294     double hy  ;
00295     hx=xmmax-xmmin;
00296     hy=ymmax-ymmin;
00297     if ( hx/(double)wmax  < hy/(double)hmax ) 
00298     {
00299       double hx1 ;
00300       hx1   = wmax * hy / hmax ;
00301       xmmin = xmmin - ( hx1 - hx ) / 2.0 ;
00302       xmmax = xmmax + ( hx1 - hx ) / 2.0 ;
00303     }
00304     else 
00305     {
00306       double hy1 ;
00307       hy1 = hmax * hx / wmax ;
00308       ymmin = ymmin - ( hy1 - hy ) / 2.0 ;
00309       ymmax = ymmax + ( hy1 - hy ) / 2.0 ;
00310     }
00311   }
00312 
00313   if (flag != 0 ) /* != using current 3D scale */
00314   {
00315     double FRect[4] ;
00316     /* FRect = [Xmin,Ymin,Xmax,Ymax] */
00317     FRect[0] =  xmmin ;
00318     FRect[1] = -ymmax ;
00319     FRect[2] =  xmmax ;
00320     FRect[3] = -ymmin ; /* 2) ... (why - (minus) ? )*/
00321     set_scale("tftttf",NULL,FRect,aaint,"nn",NULL);
00322     Cscale.metric3d = flag; 
00323   }
00324 }
00325 
00326 
00331 void Nextind(integer ind1, integer *ind2, integer *ind3)
00332 {
00333   *ind2 = ind1+1;
00334   *ind3 = ind1-1;
00335   if (ind1 > 3)
00336     {
00337       if (*ind2 == 8) *ind2 = 4;
00338       if (*ind3 == 3) *ind3 = 7;
00339     }
00340   else
00341     {
00342       if (*ind2 == 4) *ind2 = 0;
00343       if (*ind3 == -1) *ind3 = 3;
00344     }
00345 }
00346 
00347 
00348 
00349 
00350 BOOL Ishidden(sciPointObj *pobj)
00351 {
00352   double alpha;
00353   if (sciGetEntityType(pobj) == SCI_SUBWIN){
00354     alpha = pSUBWIN_FEATURE (pobj)->alpha;
00355     if ((alpha <0.0 ) && (alpha > -90.0))
00356       return TRUE;
00357     if ((alpha <360.0 ) && (alpha > 270.0)) /* missing case added to fix bug 839 F.Leray */
00358       return TRUE;
00359     if ((alpha <-180.0 ) && (alpha > -270.0))
00360       return TRUE;
00361     if ((alpha <180.0 ) && (alpha > 90.0))
00362       return TRUE;
00363   }
00364   return FALSE;
00365 }
00366 
00367 /* When alpha is close to a singularity (90,-90,270...), use to determine how to draw the x and y graduations */
00368 /* depending on cof */
00369 BOOL IsDownAxes(sciPointObj *pobj)
00370 {
00371   double alpha,cof;
00372   
00373   if (sciGetEntityType(pobj) == SCI_SUBWIN){
00374     alpha = pSUBWIN_FEATURE (pobj)->alpha;   
00375     if (!(pSUBWIN_FEATURE (pobj)->isoview))
00376       cof=10.0;
00377     else
00378       cof = 5.0; /* F.Leray : hard fixed here */
00379     if (cof == 0 ) cof =5;
00380     if ((alpha <=(-90.0+cof) ) && (alpha >= (-90.0-cof))) 
00381       return TRUE;
00382     if ((alpha <=(-270.0+cof) ) && (alpha >= (-270.0-cof)))
00383       return TRUE;
00384     if ((alpha <=(90.0+cof) ) && (alpha >= (90.0-cof)))
00385       return TRUE;
00386     if ((alpha <=(270.0+cof) ) && (alpha >= (270.0-cof)))
00387       return TRUE;
00388   }
00389   return FALSE;
00390 }
00391 
00392 /* compute the graduation of the segment [minVal,maxVal] knowing the number of ticks */
00393 void GradFixedlog( double minVal, double maxVal, double * ticks, int nbGrads )
00394 {
00395   int initSize ;
00396   int i ;
00397 
00398   /* intialize the array as usual */
00399   GradLog( minVal, maxVal, ticks, &initSize, FALSE ) ;
00400 
00401   if ( initSize > nbGrads )
00402   {
00403     /* we create a smaller vector from a bigger one */
00404     int nbRemove = initSize - nbGrads ;
00405     
00406     BOOL * removedTicks ;
00407     if( ( removedTicks = MALLOC( initSize * sizeof(BOOL) ) ) == NULL )
00408     {
00409       return ;
00410     }
00411 
00412     for ( i = 0 ; i < initSize ; i++ )
00413     {
00414       removedTicks[i] = FALSE ;
00415     }
00416 
00417     /* we now remove the nbremove indexes : round( ( 0.5 + i ) * size / nbRemove ) */
00418     /* i=0..nbReg-1 should do the thing */
00419     for ( i = 0 ; i < nbRemove ; i++ )
00420     {
00421       int remIndex = 1 + (int) round(  i  * ((double) initSize - 2 ) / ( (double) nbRemove ) ) ;
00422       removedTicks[remIndex] = TRUE ;
00423     }
00424 
00425     removeBadTicks( ticks, removedTicks, &initSize ) ;
00426 
00427     FREE( removedTicks ) ;
00428 
00429   }
00430 
00431 }
00432 
00433 
00434 /* compute the automatic graduation of the segment [_min,_max] and store it in _grads */
00435 /* the number of graduation may be fixed if compNgrads is TRUE or automaticaly computed */
00436 /* otherwise. */
00437 int GradLog( double   _min   ,
00438              double   _max   ,
00439              double * _grads ,
00440              int    * n_grads,
00441              int      compNgrads )
00442 {
00443   int i;
00444   int log_min, log_max;
00445   int size;
00446   
00447   if ( compNgrads )
00448   {
00449     GradFixedlog( _min, _max, _grads, *n_grads ) ;
00450     return 0 ;
00451   }
00452 
00453   log_max =  (int) ceil(_max);
00454   log_min =  (int) floor(_min);
00455   
00456 
00457   size = log_max - log_min +1;
00458   /*  tab=(int *)MALLOC(size*sizeof(int)); */
00459   
00460   /*   for(i=0;i<size;i++) tab[i]=log_min+i; */
00461 
00462   *n_grads = 0 ;
00463 
00464   if(size<=7)    {
00465       for(i=0;i<size;i++)
00466         {
00467           /*    _grads[i] = exp10(tab[i]); */
00468           _grads[i] = log_min+i;
00469           *n_grads = (*n_grads) + 1;
00470           /*      sciprint("Juste en sortie, _grads[%d] = %lf\n",i, _grads[i]); */
00471         }
00472     }
00473   else
00474     {
00475       int pas = 0, old_pas= 0,j;
00476       int val = size, passed = 0;
00477       
00478       for(j=val-1;j>1;j--)
00479         if(val%j == 0){
00480           old_pas = pas;
00481           pas=j; 
00482           passed = 1;
00483 
00484           if((7*pas)<=val){ 
00485             if(old_pas != 0) {pas = old_pas; }
00486             break;
00487           }
00488         }
00489       
00490       if(passed != 1 || (size/pas)>15 ) pas = size;
00491             
00492       if(pas==size)
00493         {
00494           _grads[0] = log_min;
00495           _grads[1] = log_max;
00496           *n_grads =2;
00497         }
00498       else
00499       {
00500         for(i=0;i<=(int )(size/pas);i++)
00501           {
00502             _grads[i] = log_min+(i*pas);
00503             
00504             *n_grads = (*n_grads) + 1;
00505             /*      sciprint("Juste en sortie, _grads[%d] = %lf\n",i, _grads[i]); */
00506           }
00507       }
00508     }
00509   
00510   return 0;
00511 }
00512 
00517 int sciGetLogExponent( double minBound, double maxBound, double * expMin, double * expMax )
00518 {
00519   if ( minBound > 0 )
00520   {
00521     *expMin = floor( log10( minBound ) ) ;
00522     *expMax = ceil(  log10( maxBound ) ) ;
00523     return 0 ;
00524   }
00525   *expMax = 1.0 ;
00526   *expMin = 0.0 ;
00527   return -1 ;
00528 }
00529 
00530 /* get the displayed bounds of an axis */
00531 void sciGetDisplayedBounds( sciPointObj * pSubWin,
00532                             double      * xmin   ,
00533                             double      * xmax   ,
00534                             double      * ymin   ,
00535                             double      * ymax   ,
00536                             double      * zmin   ,
00537                             double      * zmax    )
00538 {
00539   sciSubWindow * ppsubwin =  pSUBWIN_FEATURE ( pSubWin ) ;
00540     /*****************************************************************
00541      * get initial bounds
00542    *****************************************************************/
00543   if( sciGetZooming( pSubWin ) )
00544   {
00545     *xmin = ppsubwin->ZRect[0] ; 
00546     *ymin = ppsubwin->ZRect[1] ; 
00547     *xmax = ppsubwin->ZRect[2] ;
00548     *ymax = ppsubwin->ZRect[3] ;
00549     *zmin = ppsubwin->ZRect[4] ;
00550     *zmax = ppsubwin->ZRect[5] ;
00551   }
00552   else
00553   {
00554     *xmin = ppsubwin->SRect[0] ;
00555     *ymin = ppsubwin->SRect[2] ;
00556     *xmax = ppsubwin->SRect[1] ;
00557     *ymax = ppsubwin->SRect[3] ;
00558     *zmin = ppsubwin->SRect[4] ;
00559     *zmax = ppsubwin->SRect[5] ;
00560   }
00561   
00562   
00563    
00564   /*****************************************************************
00565    * modify  bounds and aaint  if using log scaling X axis
00566    *****************************************************************/
00567   if ( ppsubwin->logflags[0] == 'l' )
00568   {
00569     if ( sciGetLogExponent( *xmin, *xmax, xmin, xmax ) != 0 )
00570     {
00571       sciprint("Warning: Can't use Log on X-axis xmin is negative. \n");
00572     }
00573   }
00574 
00575   /*****************************************************************
00576    * modify  bounds and aaint  if using log scaling Y axis
00577    *****************************************************************/
00578   if ( ppsubwin->logflags[1] == 'l' )
00579   {
00580     if ( sciGetLogExponent( *ymin, *ymax, ymin, ymax ) != 0 )
00581     {
00582       sciprint("Warning: Can't use Log on Y-axis ymin is negative. \n");
00583     }
00584   }
00585 
00586   /*****************************************************************
00587    * modify  bounds and aaint  if using log scaling Z axis
00588    *****************************************************************/
00589   if ( ppsubwin->logflags[2] == 'l' )
00590   {
00591     if ( sciGetLogExponent( *zmin, *zmax, zmin, zmax ) != 0 )
00592     {
00593       sciprint("Warning: Can't use Log on Z-axis zmin is negative. \n");
00594     }
00595   }
00596 
00597 }
00598 
00599 /* F.Leray au 13.10.04 completly review for new axes graduations */
00600 /*** F.Leray 02.04.04 */
00601 /* FUNCTION FOR 2D UPDATE ONLY !!!!! <=> beginning of axis_3ddraw (in 2d HERE of course! ) */
00602 /* Copy on update_frame_bounds */
00603 BOOL sci_update_frame_bounds_2d(sciPointObj *pobj)
00604 {
00605   double xmax, xmin, ymin, ymax, zmin, zmax ;
00606   double hx,hy,hx1,hy1;
00607   int i;
00608   
00609   sciSubWindow * ppsubwin =  pSUBWIN_FEATURE (pobj);
00610   double FRect[4],WRect[4],ARect[4]; 
00611   char logscale[2];
00612   
00613   /* Temp variables only used when called from update_specification_bounds */
00614   /* to know if we have to redraw all the figure */
00615   double ExistingFRect[4]; /* the Existing FRect at start to be compared at the end of this routine */
00616   /* in order to determine wheter or not the bounds have changed... */
00617   int nbsubtics[2];
00618   int nbgrads[2];
00619   /* End of Temp variables */
00620   
00621   for(i=0;i<4;i++) ExistingFRect[i] =  ppsubwin->FRect[i]; /* store old initial bounds*/
00622 
00623   for(i=0;i<2;i++) nbsubtics[i] = ppsubwin->axes.nbsubtics[i];
00624   nbgrads[0] = ppsubwin->axes.nxgrads;
00625   nbgrads[1] = ppsubwin->axes.nygrads;
00626   
00627   /* nbtics on z put to 0 */
00628   /*   ppsubwin->axes.nzgrads = 0; */
00629   
00630 
00631   sciGetDisplayedBounds( pobj, &xmin, &xmax, &ymin, &ymax, &zmin, &zmax ) ;
00632 
00633 
00634   /* _grad Init. to 0. */
00635   for(i=0;i<20;i++) 
00636     {
00637       ppsubwin->axes.xgrads[i] = 0.;
00638       ppsubwin->axes.ygrads[i] = 0.;
00639     }
00640    
00641  
00642   if ( ppsubwin->logflags[0]=='n') { /* x-axis */
00643     TheTicks(&xmin, &xmax, &(ppsubwin->axes.xgrads[0]), &ppsubwin->axes.nxgrads, FALSE); 
00644     ppsubwin->axes.nbsubtics[0] = ComputeNbSubTics(pobj,ppsubwin->axes.nxgrads,'n',NULL,ppsubwin->axes.nbsubtics[0]); /* Nb of subtics computation and storage */ /* F.Leray 07.10.04 */
00645   }
00646   else{ /* log. case */
00647     GradLog(xmin,xmax,ppsubwin->axes.xgrads,&ppsubwin->axes.nxgrads, FALSE );
00648     ppsubwin->axes.nbsubtics[0] = ComputeNbSubTics(pobj,ppsubwin->axes.nxgrads,'l',ppsubwin->axes.xgrads,0);
00649   }
00650    
00651   if ( ppsubwin->logflags[1]=='n') { /* y-axis */
00652     TheTicks(&ymin, &ymax, &(ppsubwin->axes.ygrads[0]), &ppsubwin->axes.nygrads, FALSE);
00653     ppsubwin->axes.nbsubtics[1] = ComputeNbSubTics(pobj,ppsubwin->axes.nygrads,'n',NULL, ppsubwin->axes.nbsubtics[1]); /* Nb of subtics computation and storage */ /* F.Leray 07.10.04 */
00654   }
00655   else{ /* log. case */
00656     GradLog(ymin,ymax,ppsubwin->axes.ygrads,&ppsubwin->axes.nygrads, FALSE );
00657     ppsubwin->axes.nbsubtics[1] = ComputeNbSubTics(pobj,ppsubwin->axes.nygrads,'l',ppsubwin->axes.ygrads,0);
00658   }
00659    
00660   if(ppsubwin->tight_limits == FALSE )
00661     {
00662       xmin = ppsubwin->axes.xgrads[0];
00663       xmax = ppsubwin->axes.xgrads[ ppsubwin->axes.nxgrads - 1];
00664       ymin = ppsubwin->axes.ygrads[0];
00665       ymax = ppsubwin->axes.ygrads[ ppsubwin->axes.nygrads - 1];
00666     }
00667 
00668   /*****************************************************************
00669    * modify  bounds if  isoview requested 
00670    *****************************************************************/
00671   if ( ppsubwin->isoview == TRUE) {      
00672     int verbose=0,wdim[2],narg; 
00673         
00674     C2F(dr)("xget","wdim",&verbose,wdim,&narg, PI0, PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
00675     hx=xmax-xmin;
00676     hy=ymax-ymin;
00677     getscale2d(WRect,FRect,logscale,ARect);
00678     
00679     wdim[0]=linint((double)wdim[0] *WRect[2]);
00680     wdim[1]=linint((double)wdim[1] *WRect[3]);
00681     
00682     if ( hx/(double)wdim[0]  <hy/(double) wdim[1] ) {
00683       hx1=wdim[0]*hy/wdim[1];
00684       xmin=xmin-(hx1-hx)/2.0;
00685       xmax=xmax+(hx1-hx)/2.0;
00686     }
00687     else {
00688       hy1=wdim[1]*hx/wdim[0];
00689       ymin=ymin-(hy1-hy)/2.0;
00690       ymax=ymax+(hy1-hy)/2.0;
00691     }
00692     
00693     /* F.Leray 28.09.04 */
00694     /* I need to recompute the correct xgrads and ygrads vector to have a good display */
00695      
00696     if ( ppsubwin->logflags[0]=='n') { /* x-axis */
00697       TheTicks(&xmin, &xmax, &(ppsubwin->axes.xgrads[0]), &ppsubwin->axes.nxgrads, FALSE);
00698       ppsubwin->axes.nbsubtics[0] = ComputeNbSubTics(pobj,ppsubwin->axes.nxgrads,'n',NULL, ppsubwin->axes.nbsubtics[0]); /* Nb of subtics computation and storage */ /* F.Leray 07.10.04 */
00699     }
00700     else{ /* log. case */
00701       GradLog(xmin,xmax,ppsubwin->axes.xgrads,&ppsubwin->axes.nxgrads, FALSE);
00702       ppsubwin->axes.nbsubtics[0] = ComputeNbSubTics(pobj,ppsubwin->axes.nxgrads,'l',ppsubwin->axes.xgrads,0);
00703     }
00704 
00705  
00706 
00707     if ( ppsubwin->logflags[1]=='n') { /* y-axis */
00708       TheTicks(&ymin, &ymax, &(ppsubwin->axes.ygrads[0]), &ppsubwin->axes.nygrads, FALSE);
00709       ppsubwin->axes.nbsubtics[1] = ComputeNbSubTics(pobj,ppsubwin->axes.nygrads,'n',NULL, ppsubwin->axes.nbsubtics[1]); /* Nb of subtics computation and storage */ /* F.Leray 07.10.04 */
00710     }
00711     else{ /* log. case */
00712       GradLog(ymin,ymax,ppsubwin->axes.ygrads,&ppsubwin->axes.nygrads, FALSE );
00713       ppsubwin->axes.nbsubtics[1] = ComputeNbSubTics(pobj,ppsubwin->axes.nygrads,'l',ppsubwin->axes.ygrads,0);
00714     }
00715    
00716    
00717     /* END ISO if */
00718   }
00719   
00720   /* Changement ci-dessous F.Leray 21.09.04 */
00721   ppsubwin->axes.xlim[0]=xmin;
00722   ppsubwin->axes.xlim[1]=xmax;
00723   ppsubwin->axes.xlim[2]=0;
00724   ppsubwin->axes.ylim[0]=ymin;
00725   ppsubwin->axes.ylim[1]=ymax;
00726   ppsubwin->axes.ylim[2]=0;
00727    
00728    
00729    
00730   /*****************************************************************
00731    * set the actual bounds in subwindow data structure
00732    *****************************************************************/
00733    
00734    
00735   ppsubwin->FRect[0]=xmin;
00736   ppsubwin->FRect[2]=xmax;
00737   ppsubwin->FRect[1]=ymin;
00738   ppsubwin->FRect[3]=ymax;
00739    
00740   ppsubwin->axes.xlim[3] = ppsubwin->axes.nxgrads;
00741   ppsubwin->axes.ylim[3] = ppsubwin->axes.nygrads;
00742    
00743   /*   ppsubwin->axes.reverse[0] = FALSE; /\*TRUE;*\/  /\* TEST en DUR F.Leray ICIIIIIIIIIIIII 12.10.04 *\/ */
00744   /*    ppsubwin->axes.reverse[1] = FALSE; /\*TRUE;*\/  */
00745    
00746    
00747   set_scale("tftftf",NULL,ppsubwin->FRect,NULL,ppsubwin->logflags,NULL); 
00748    
00749    
00750   for(i=0;i<4;i++)
00751     if(ppsubwin->FRect[i] != ExistingFRect[i]){
00752       return TRUE;
00753       break;
00754     } 
00755    
00756   for(i=0;i<2;i++) 
00757     if(nbsubtics[i] != ppsubwin->axes.nbsubtics[i]){
00758       return TRUE;
00759       break;
00760     }
00761    
00762   if(nbgrads[0] != ppsubwin->axes.nxgrads) return TRUE;
00763   if(nbgrads[1] != ppsubwin->axes.nygrads) return TRUE;
00764    
00765   return FALSE;
00766 }
00767 
00772 BOOL sci_update_frame_bounds_3d(sciPointObj *pobj)
00773 {
00774   double xmin,xmax,ymin,ymax,zmin,zmax; 
00775   int i;
00776   sciSubWindow * ppsubwin = pSUBWIN_FEATURE (pobj); 
00777 
00778   /* Temp variables only used when called from update_specification_bounds */
00779   /* to know if we have to redraw all the figure */
00780   double ExistingFRect[6]; /* the Existing FRect at start to be compared at the end of this routine */
00781   /* in order to determine wheter or not the bounds have changed... */
00782   int nbsubtics[3];
00783   int nbgrads[3];
00784   /* End of Temp variables */
00785 
00786   for(i=0;i<6;i++) ExistingFRect[i] =  ppsubwin->FRect[i]; /* store old initial bounds*/
00787   
00788   for(i=0;i<3;i++) nbsubtics[i] = ppsubwin->axes.nbsubtics[i];
00789   nbgrads[0] = ppsubwin->axes.nxgrads;
00790   nbgrads[1] = ppsubwin->axes.nygrads;
00791   nbgrads[2] = ppsubwin->axes.nzgrads;
00792 
00793   sciGetDisplayedBounds( pobj, &xmin, &xmax, &ymin, &ymax, &zmin, &zmax ) ;
00794   
00795 
00796   /* _grad Init. to 0. */
00797   for(i=0;i<20;i++) 
00798     {
00799       ppsubwin->axes.xgrads[i] = 0.;
00800       ppsubwin->axes.ygrads[i] = 0.;
00801       ppsubwin->axes.zgrads[i] = 0.;
00802     }
00803    
00804   
00805   if ( ppsubwin->logflags[0]=='n') { /* x-axis */
00806     TheTicks(&xmin, &xmax, &(ppsubwin->axes.xgrads[0]), &ppsubwin->axes.nxgrads, FALSE);
00807     ppsubwin->axes.nbsubtics[0] = ComputeNbSubTics(pobj,ppsubwin->axes.nxgrads,'n',NULL,ppsubwin->axes.nbsubtics[0]); /* Nb of subtics computation and storage */
00808   }
00809   else{ /* log. case */
00810     GradLog(xmin,xmax,ppsubwin->axes.xgrads,&ppsubwin->axes.nxgrads, FALSE );
00811     ppsubwin->axes.nbsubtics[0] = ComputeNbSubTics(pobj,ppsubwin->axes.nxgrads,'l',ppsubwin->axes.xgrads,0);
00812   }
00813   
00814   if ( ppsubwin->logflags[1]=='n') { /* y-axis */
00815     TheTicks(&ymin, &ymax, &(ppsubwin->axes.ygrads[0]), &ppsubwin->axes.nygrads, FALSE);
00816     ppsubwin->axes.nbsubtics[1] = ComputeNbSubTics(pobj,ppsubwin->axes.nygrads,'n',NULL, ppsubwin->axes.nbsubtics[1]); /* Nb of subtics computation and storage */
00817   }
00818   else{ /* log. case */
00819     GradLog(ymin,ymax,ppsubwin->axes.ygrads,&ppsubwin->axes.nygrads, FALSE );
00820     ppsubwin->axes.nbsubtics[1] = ComputeNbSubTics(pobj,ppsubwin->axes.nygrads,'l',ppsubwin->axes.ygrads,0);
00821   }
00822   
00823   if ( ppsubwin->logflags[2]=='n') { /* z-axis */
00824     TheTicks(&zmin, &zmax, &(ppsubwin->axes.zgrads[0]), &ppsubwin->axes.nzgrads, FALSE);
00825     ppsubwin->axes.nbsubtics[2] = ComputeNbSubTics(pobj,ppsubwin->axes.nzgrads,'n',NULL, ppsubwin->axes.nbsubtics[2]); /* Nb of subtics computation and storage */
00826   }
00827   else{ /* log. case */
00828     GradLog(zmin,zmax,ppsubwin->axes.zgrads,&ppsubwin->axes.nzgrads, FALSE );
00829     ppsubwin->axes.nbsubtics[2] = ComputeNbSubTics(pobj,ppsubwin->axes.nzgrads,'l',ppsubwin->axes.zgrads,0);
00830   }
00831   
00832   if(ppsubwin->tight_limits == FALSE )
00833     {
00834       xmin = ppsubwin->axes.xgrads[0];
00835       xmax = ppsubwin->axes.xgrads[ ppsubwin->axes.nxgrads - 1];
00836       ymin = ppsubwin->axes.ygrads[0];
00837       ymax = ppsubwin->axes.ygrads[ ppsubwin->axes.nygrads - 1];
00838       zmin = ppsubwin->axes.zgrads[0];
00839       zmax = ppsubwin->axes.zgrads[ ppsubwin->axes.nzgrads - 1];
00840     }
00841 
00842   ppsubwin->axes.xlim[0]=xmin;
00843   ppsubwin->axes.xlim[1]=xmax;
00844   ppsubwin->axes.xlim[2]=0;
00845   ppsubwin->axes.ylim[0]=ymin;
00846   ppsubwin->axes.ylim[1]=ymax;
00847   ppsubwin->axes.ylim[2]=0;
00848   ppsubwin->axes.zlim[0]=zmin; /* rajout pour z */
00849   ppsubwin->axes.zlim[1]=zmax;
00850   ppsubwin->axes.zlim[2]=0;
00851      
00852   ppsubwin->FRect[0]=xmin;
00853   ppsubwin->FRect[2]=xmax;
00854   ppsubwin->FRect[1]=ymin;
00855   ppsubwin->FRect[3]=ymax;
00856   ppsubwin->FRect[4]=zmin;
00857   ppsubwin->FRect[5]=zmax;
00858     
00859   ppsubwin->axes.xlim[3] = ppsubwin->axes.nxgrads;
00860   ppsubwin->axes.ylim[3] = ppsubwin->axes.nygrads;
00861   ppsubwin->axes.zlim[3] = ppsubwin->axes.nzgrads;
00862    
00863   set_scale("tftftf",NULL,ppsubwin->FRect,NULL,ppsubwin->logflags,NULL); 
00864     
00865   for(i=0;i<6;i++)
00866     if(ppsubwin->FRect[i] != ExistingFRect[i]){
00867       return TRUE;
00868       break;
00869     } 
00870     
00871   for(i=0;i<3;i++) 
00872     if(nbsubtics[i] != ppsubwin->axes.nbsubtics[i]){
00873       return TRUE;
00874       break;
00875     }
00876   
00877   if(nbgrads[0] != ppsubwin->axes.nxgrads) return TRUE;
00878   if(nbgrads[1] != ppsubwin->axes.nygrads) return TRUE;
00879   if(nbgrads[2] != ppsubwin->axes.nzgrads) return TRUE;
00880   
00881   return FALSE;  
00882 }
00883 
00884 
00885 
00886 
00887 
00888 
00889 
00890 int ComputeNbSubTics(sciPointObj * pobj, int nbtics, char logflag, double * grads, int nbsubtics_input)
00891 {
00892   int ticsval[] =    {2 ,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
00893   int subticsval[] = {10,7,5,5,4,4,3,2,2 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 };
00894   int i;
00895   sciSubWindow * ppsubwin = pSUBWIN_FEATURE (pobj);
00896 
00897 
00898   if(logflag =='l'){
00899     if((grads[1]-grads[0])==1) /* intervalle de type ...10^n 10^(n+1)...*/
00900       {
00901         return 9; /* 9 subtics to have a pretty tics/grid in log.*/
00902       }
00903     else
00904       {
00905         return 1; /* no subtics at all (1 but draw on a tics place) */
00906       }
00907   }
00908   else{
00909     if(ppsubwin->flagNax == FALSE) /* if auto subtics mode == ON */
00910       { 
00911         for(i=0;i<19;i++)
00912           if(nbtics == ticsval[i])
00913             {
00914               return subticsval[i];
00915             }
00916       }
00917     else /* if auto subtics mode == OFF already computed in Plo2dn.c, Champ.c routines... */
00918       {  /* or given via a.subtics=[nbsubtics_on_x, nbsubtics_on_y, nbsubtics_on_z] command */
00919         return nbsubtics_input;
00920       }
00921   }
00922   
00923   return -1;
00924 }
00925 
00926 /* test on x and y axes only : used in 2D routines only */
00927 BOOL GetIsAxes2D(sciPointObj *psubwin)
00928 {
00929   sciSubWindow * ppsubwin = pSUBWIN_FEATURE (psubwin);
00930   
00931   if((ppsubwin->axes.axes_visible[0] == FALSE)
00932      && (ppsubwin->axes.axes_visible[1] == FALSE))
00933     return FALSE;
00934   else
00935     return TRUE;
00936 }
00937 
00938 int ComputeCorrectXindAndInsideUD(double Teta,double Alpha, double *dbox, integer *xind, integer *InsideU, integer *InsideD)
00939 {
00940   double xbox[8], ybox[8], zbox[8];
00941 
00942   Teta = 0.1; /* Little offset to compute correct values for xind,  InsideU and InsideD */
00943 
00944   /* update Cscale.m from the new viewing angles */
00945   sciUpdateScaleAngles( Teta, Alpha ) ;
00946  
00947   sciGetAxisBox( dbox, xbox, ybox, zbox ) ;
00948  
00949   sciAxesVerticesIndices( InsideU, InsideD, xbox, ybox, xind ) ;
00950 
00951   return 0;
00952 }
00953 
00954 
00955 
00956 int ComputeGoodTrans3d( sciPointObj * psubwin, int n, int *xm, int *ym, double * fx, double *fy, double *fz)
00957 {
00958   sciSubWindow * ppsubwin = pSUBWIN_FEATURE(psubwin);
00959 
00960   
00961   double tmp_fx = *fx;
00962   double tmp_fy = *fy;
00963   double tmp_fz = *fz;
00964   
00965   if(ppsubwin->logflags[0] == 'l')
00966     tmp_fx = exp10(tmp_fx);
00967   
00968   if(ppsubwin->logflags[1] == 'l')
00969     tmp_fy = exp10(tmp_fy);
00970   
00971   if(ppsubwin->logflags[2] == 'l')
00972     tmp_fz = exp10(tmp_fz);
00973   
00974   trans3d(psubwin, n, xm, ym, &tmp_fx, &tmp_fy, &tmp_fz);
00975   
00976   return 0;
00977 }
00978 
00979 
00987 void DrawAxesIfRequired(sciPointObj * pobj)
00988 {
00989   sciPointObj * pfigure = sciGetParentFigure(pobj);
00990   
00991   if( pFIGURE_FEATURE(pfigure)->auto_redraw && pFIGURE_FEATURE(pfigure)->visible )
00992   {
00993     DrawAxes(pobj);
00994   }
00995   
00996 }
00997 
00998 /* Routine used inside Plo2dn.c, Champ.c, Gray.c... */
00999 /* to force the drawing of the axes after a new object is created */
01000 void DrawAxes(sciPointObj * pobj)
01001 {
01002   sciPointObj * psubwin = sciGetParentSubwin(pobj);
01003   /*   sciPointObj * pfigure = sciGetParentFigure(pobj); */
01004   char STRFLAG[4];
01005   integer x[6], v, markidsizenew[2];
01006   double dv;
01007 
01008   if (!sciGetVisibility(pobj)) return;
01009   
01010   x[0] = sciGetForeground (psubwin);
01011   x[2] = sciGetLineWidth (psubwin);
01012   x[3] = sciGetLineStyle (psubwin);
01013   markidsizenew[0] = sciGetMarkStyle(psubwin);
01014   markidsizenew[1] = sciGetLineWidth (psubwin);
01015   x[4] = 0;
01016   v = 0;
01017   dv = 0;
01018 
01019   
01020   sciSetSelectedSubWin(psubwin); 
01021   
01022   set_scale ("tttftt", pSUBWIN_FEATURE (psubwin)->WRect, pSUBWIN_FEATURE (psubwin)->FRect,
01023              NULL, pSUBWIN_FEATURE (psubwin)->logflags, 
01024              pSUBWIN_FEATURE (psubwin)->ARect); 
01025      
01026   if (!pSUBWIN_FEATURE (psubwin)->is3d)   /* we are in 2D mode...*/
01027     {
01028       /* F.Leray 07.12.04 */
01029       /* TO CORRECT the bug 1115 : Big object (grayplots) could cover axes*/
01030       C2F (dr) ("xset","dashes",x,x,x+4,x+4,x+4,&v,&dv,&dv,&dv,&dv,5L,4096);
01031       C2F (dr) ("xset","foreground",x,x,x+4,x+4,x+4,&v,&dv,&dv,&dv,&dv,5L,4096);
01032       C2F (dr) ("xset","thickness",x+2,PI0,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
01033       C2F (dr) ("xset","mark",&markidsizenew[0],&markidsizenew[1],PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
01034 
01035       rebuild_strflag(psubwin,STRFLAG);
01036       axis_draw2 (STRFLAG); /* Axes is rebuilt here to avoid being covered by the new created object */
01037     }
01038 }
01039 
01040 
01041 /* Used only when switching from a plot3d to a plot2d or 
01042  * when typing: a=gca();
01043  *              a.view='2d' and we were in 3d 
01044  * to have a good update of 3d graphics scale in 2D
01045  * whenever we are in auto_redraw OFF  */
01046 void UpdateSubwinScale(sciPointObj * pobj)
01047 {
01048   sciSubWindow * ppsubwin = pSUBWIN_FEATURE (pobj);
01049   sciPointObj * currentsubwin = NULL;
01050   BOOL vis_save = FALSE;
01051   double xbox[8],ybox[8],zbox[8];
01052   static integer InsideU[4],InsideD[4];
01053         
01054   currentsubwin = sciGetCurrentSubWin();
01055 
01056   sciSetSelectedSubWin(pobj); 
01057   
01058   /*   set_scale ("tttftt", pSUBWIN_FEATURE (pobj)->WRect, pSUBWIN_FEATURE (pobj)->FRect, */
01059   /*         NULL, pSUBWIN_FEATURE (pobj)->logflags,  */
01060   /*         pSUBWIN_FEATURE (pobj)->ARect);  */
01061   
01062   if (ppsubwin->is3d) 
01063     {  /* 3D Coordinates */ /* verifier si c'est encore utile SS */
01064       /*To have directly all the possible ISOVIEW Modes*/
01065       long isoflag = (long)(ppsubwin->axes.flag[1]+1)/2; 
01066       
01067       if(ppsubwin->isoview == TRUE) {
01068         if(isoflag ==2 || isoflag == 3){                }
01069         else {
01070           if((ppsubwin->axes.flag[1] == 0)
01071              || (ppsubwin->axes.flag[1] == 2))
01072             /* The default isoview mode is type=4 3d isometric bounds 
01073                derived from the data, to similarily type=2  */
01074             ppsubwin->axes.flag[1] = 4; 
01075           else if(ppsubwin->axes.flag[1] == 1)
01076             ppsubwin->axes.flag[1] = 3;
01077         }
01078       }
01079       else {
01080         if((ppsubwin->axes.flag[1] == 3) 
01081            || (ppsubwin->axes.flag[1] == 5))
01082           ppsubwin->axes.flag[1] = 1; /* computed from ebox*/
01083         else if((ppsubwin->axes.flag[1] == 4) 
01084                 || (ppsubwin->axes.flag[1] == 6))
01085           /* The default NON-isoview mode is 2 computed from data*/
01086           ppsubwin->axes.flag[1] = 2; 
01087       }
01088       
01089 
01090       vis_save = sciGetVisibility(pobj);
01091 
01092       sciSetVisibility(pobj,FALSE);
01093       axis_3ddraw(pobj,xbox,ybox,zbox,InsideU,InsideD); /* TEST on sciGetVisibility inside */
01094       /* because axis_3ddraw displays 3d axes BUT ALSO compute + reset the 3d scale BEFORE !! */
01095       sciSetVisibility(pobj,vis_save);
01096     }
01097   else /* we are in 2D mode...*/
01098     {
01099       sci_update_frame_bounds_2d(pobj);
01100     }
01101 
01102   sciSetSelectedSubWin(currentsubwin); 
01103   
01104 }
01105 
01106 int Gen3DPoints(integer type,integer *polyx, integer *polyy, integer *fill, integer whiteid, double zmin, double zmax, double *x, double *y, double *z, integer i, integer j, integer jj1, integer *p, integer dc, integer fg, sciPointObj * psurface)
01107 {
01108   sciPointObj *pobj;
01109   int facteur = 1;
01110 
01111   sciPointObj *psubwin = sciGetCurrentSubWin();
01112   sciSubWindow * ppsubwin = pSUBWIN_FEATURE(psubwin);
01113   sciSurface * ppsurface = pSURFACE_FEATURE (psurface);
01114   
01115   pobj = sciGetCurrentSubWin(); 
01116   if (trans3d(pobj ,1, &(polyx[  5*jj1]),&(polyy[  5*jj1]),&(x[i]),&(y[j]),&(z[i+(*p)*j]))==0) return 0; 
01117   if (trans3d(pobj ,1, &(polyx[1+  5*jj1]),&(polyy[1+  5*jj1]),&(x[i]),&(y[j+1]),&(z[i+(*p)*(j+1)]))==0) return 0; 
01118   if (trans3d(pobj ,1, &(polyx[2+  5*jj1]),&(polyy[2+  5*jj1]),&(x[i+1]),&(y[j+1]),&(z[(i+1)+(*p)*(j+1)]))==0) return 0; 
01119   if (trans3d(pobj ,1, &(polyx[3+  5*jj1]),&(polyy[3+  5*jj1]),&(x[i+1]),&(y[j]),&(z[(i+1)+(*p)*j]))==0) return 0;   
01120   if (trans3d(pobj ,1, &(polyx[4+  5*jj1]),&(polyy[4+  5*jj1]),&(x[i]),&(y[j]),&(z[i+(*p)*j]))==0) return 0; 
01121   
01122   
01123   if(ppsubwin->axes.reverse[0] == TRUE) facteur = -facteur;
01124   if(ppsubwin->axes.reverse[1] == TRUE) facteur = -facteur;
01125   if(ppsubwin->axes.reverse[2] == TRUE) facteur = -facteur;
01126   
01127   /* try */
01128   facteur = ppsurface->flag_x * ppsurface->flag_y * facteur;
01129   
01130   /* type == flagcolor and dc == color_mode */
01131   /* fg = hidden color */
01132   
01133   if ((((polyx[1+5*jj1]-polyx[0+5*jj1])*(polyy[2+5*jj1]-polyy[0+5*jj1])-
01134         (polyy[1+5*jj1]-polyy[0+5*jj1])*(polyx[2+5*jj1]-polyx[0+5*jj1]))*facteur <  0) && (fg >=0 )) 
01135     {
01136       
01137       /* ------------------- */
01138       /* Beneath the surface */
01139       /* ------------------- */
01140 
01141       if (type != 0) /* flagcolor = 1 case : special treatment compared to flagcolor = 0 */
01142                      /* don't know why... F.Leray */
01143         fill[jj1]= (dc < 0 ) ? -fg : fg ;
01144       else           /* flagcolor = 0 :  No shading at all, fixed facecolor. */
01145         fill[jj1]=  (dc != 0 ) ? fg : dc ;
01146     }
01147   else
01148     {
01149 
01150       /* ------------------- */
01151       /* Above the surface */
01152       /* ------------------- */
01153 
01154      if (type != 0)
01155         {  /* flagcolor = 1 :  Z-level flat shading. */
01156           fill[jj1]=inint((whiteid-1)*((1/4.0*( z[i+(*p)*j]+ z[i+1+(*p)*j]+
01157                                                 z[i+(*p)*(j+1)]+ z[i+1+(*p)*(j+1)])-zmin)
01158                                        /(zmax-zmin)))+1;
01159           if ( dc < 0 ) fill[jj1]= -fill[jj1];  
01160         }
01161       else
01162         fill[jj1]= dc;     
01163     }
01164   
01165   return(1);
01166   
01167 }
01168 
01169 
01170 
01171 int Merge3dDimension(sciPointObj *pparent)
01172 {
01173   integer N,q; 
01174   sciSons *psonstmp;
01175 
01176   /* ========================================================================
01177    * Compute the number of facets, segments,... included in all the subwin 
01178    * children
01179    * Each entities to merge; is decomposed in a set of basic elements 
01180    *  (facet, segment, point,...)
01181    * Each basic element is represented in the Merge structure by the handle of its entity and an 
01182    *   index within this entity
01183    * ========================================================================*/
01184 
01185   q=0;
01186   psonstmp = sciGetSons (pparent);
01187   while (psonstmp != (sciSons *) NULL) {   
01188     switch (sciGetEntityType (psonstmp->pointobj)) {  
01189     case SCI_SURFACE:
01190       if (pSURFACE_FEATURE (psonstmp->pointobj)->typeof3d == SCI_PLOT3D) 
01191         N=(pSURFACE_FEATURE (psonstmp->pointobj)->dimzx-1)*(pSURFACE_FEATURE (psonstmp->pointobj)->dimzy-1);
01192       else
01193         N = pSURFACE_FEATURE (psonstmp->pointobj)->dimzy;
01194       break;
01195 
01196     case  SCI_POLYLINE:
01197       {
01198         if ( pPOLYLINE_FEATURE(psonstmp->pointobj)->n1 == 0 )
01199         {
01200           N = 0 ;
01201         }
01202         else if (pPOLYLINE_FEATURE (psonstmp->pointobj)->plot != 5)
01203         {/*polyline*/
01204           N = pPOLYLINE_FEATURE (psonstmp->pointobj)->n1-1;
01205           if ((pPOLYLINE_FEATURE (psonstmp->pointobj)->plot != 2) && 
01206             (sciGetIsMark((sciPointObj *)psonstmp->pointobj) == 1))
01207           {
01208             N = N + 1 ;
01209           }
01210         }
01211         else /* patch */
01212         {
01213           N = 1 ;
01214         }
01215       }
01216       break;
01217     case  SCI_SEGS:
01218       {
01219         sciSegs * ppSegs = pSEGS_FEATURE(psonstmp->pointobj) ;
01220         if ( ppSegs->ptype == 0 )
01221         { 
01222           N = ppSegs->Nbr1 / 2 ;
01223         }
01224         else
01225         {
01226           N = ppSegs->Nbr1 * ppSegs->Nbr2 ;
01227         }
01228       }
01229       break;
01230     case  SCI_RECTANGLE: 
01231       N = 4;
01232       break;
01233     case SCI_AGREG:
01234       N =  Merge3dDimension(psonstmp->pointobj);
01235       break;
01236     default:
01237       N=0;
01238     }
01239     q+=N;
01240     psonstmp = psonstmp->pnext;
01241   }
01242 
01243   return q;
01244 }
01245 
01246 int ChildrenCounter(sciPointObj *pparent)
01247 {
01248   int N,q=0;
01249   sciSons * psonstmp = sciGetSons (pparent);
01250   
01251   while (psonstmp != (sciSons *) NULL) {   
01252     switch (sciGetEntityType (psonstmp->pointobj)) {  
01253     case SCI_SURFACE:
01254       N=1;
01255       break;
01256     case  SCI_POLYLINE:
01257       N = 1; 
01258       break;
01259     case  SCI_SEGS: 
01260       N=1;
01261       break;
01262     case  SCI_RECTANGLE: 
01263       N = 1;
01264       break;
01265     case SCI_AGREG:
01266       N = ChildrenCounter(psonstmp->pointobj);
01267       break;
01268     default:
01269       N=0;
01270     }
01271     q+=N;
01272     psonstmp = psonstmp->pnext;
01273   }
01274 
01275   return q;
01276 }
01277 
01278 
01279 void Merge3dBuildTable(sciPointObj *pparent, int *index_in_entity, long *from_entity, int *pos)
01280 {
01281   sciSons *psonstmp;
01282   int i,N;
01283 
01284   psonstmp = sciGetSons (pparent);
01285 
01286   while (psonstmp != (sciSons *) NULL) {   
01287     switch (sciGetEntityType (psonstmp->pointobj)) {  
01288     case SCI_SURFACE:
01289       if (pSURFACE_FEATURE (psonstmp->pointobj)->typeof3d == SCI_PLOT3D) 
01290         N=(pSURFACE_FEATURE (psonstmp->pointobj)->dimzx-1)*(pSURFACE_FEATURE (psonstmp->pointobj)->dimzy-1);
01291       else
01292         N = pSURFACE_FEATURE (psonstmp->pointobj)->dimzy;
01293       break;
01294     case  SCI_POLYLINE:
01295       if ( pPOLYLINE_FEATURE(psonstmp->pointobj)->n1 == 0 )
01296       {
01297         N = 0 ;
01298       }
01299       else if (pPOLYLINE_FEATURE (psonstmp->pointobj)->plot != 5)
01300       {/*polyline*/
01301         N = pPOLYLINE_FEATURE (psonstmp->pointobj)->n1-1;
01302         if ((pPOLYLINE_FEATURE (psonstmp->pointobj)->plot != 2) && 
01303             (sciGetIsMark((sciPointObj *)psonstmp->pointobj) == 1))
01304         {
01305           N = N + 1 ;
01306         }
01307       }
01308       else /* patch */
01309       {
01310         N = 1 ;
01311       }
01312       break;
01313     case  SCI_SEGS: 
01314       {
01315         sciSegs * ppSegs = pSEGS_FEATURE(psonstmp->pointobj) ;
01316         if ( ppSegs->ptype == 0 )
01317         { 
01318           N = ppSegs->Nbr1 / 2 ;
01319         }
01320         else
01321         {
01322           N = ppSegs->Nbr1 * ppSegs->Nbr2 ;
01323         }
01324       }
01325       break;
01326     case  SCI_RECTANGLE: 
01327       N = 4;
01328       break;
01329     case SCI_AGREG:
01330       Merge3dBuildTable(psonstmp->pointobj, index_in_entity, from_entity, pos);
01331       break;
01332     default:
01333       N = 0;
01334     }
01335     if (sciGetEntityType (psonstmp->pointobj) != SCI_AGREG)
01336       for (i=0 ; i<N; i++) {
01337         index_in_entity[*pos]=i;
01338         from_entity[*pos]=(long) sciGetHandle (psonstmp->pointobj);
01339         *pos=*pos+1;
01340       }
01341     psonstmp = psonstmp->pnext;
01342   }
01343 }
01344 
01345 
01346 void Merge3d(sciPointObj *psubwin)
01347 {
01348   integer q,k; 
01349   sciPointObj *pmerge; 
01350   int *index_in_entity;
01351   long *from_entity;
01352   
01353   if(sciGetEntityType (psubwin) != SCI_SUBWIN) return; 
01354   if ((pmerge= sciGetMerge(psubwin)) != (sciPointObj *) NULL)
01355     DestroyMerge(pmerge); 
01356   
01357   /* ========================================================================
01358    * Compute the number of facets, segments,... included in all the subwin 
01359    * children
01360    * ========================================================================*/
01361   
01362   
01363   q =  Merge3dDimension(psubwin);
01364   
01365   
01366   /* ========================================================================
01367    * allocate tables for index and handles
01368    * ========================================================================*/
01369   
01370   /* q now contains the total number of elements */
01371   if ((index_in_entity = (int *) MALLOC (q * sizeof (int))) == (int *)NULL) {
01372     sciprint("Merge3d : not enough memory to allocate \n");
01373     return;
01374   }
01375   if ((from_entity   = (long *) MALLOC (q * sizeof (long))) == (long *) NULL) {
01376     sciprint("Merge3d : not enough memory to allocate \n");
01377     FREE(index_in_entity);
01378   }
01379   
01380   /* ========================================================================
01381    * fill the index and handles tables
01382    * ========================================================================*/
01383   k=0;
01384   Merge3dBuildTable(psubwin, index_in_entity, from_entity, &k);
01385   
01386   /* ========================================================================
01387    * create the Merge data structure
01388    * ========================================================================*/
01389   
01390   if ((pmerge=ConstructMerge ((sciPointObj *) psubwin,q,index_in_entity,from_entity)) == (sciPointObj *) NULL) {
01391     FREE(index_in_entity);
01392     FREE(from_entity);
01393     sciprint ("\r\n No merge supported");}
01394   else /* inform the subwindow to display Merge instead of individual children */
01395     pSUBWIN_FEATURE (psubwin)->facetmerge = TRUE;
01396   
01397 }
01398 
01399 /*------------------------------------------------------------------------------------------*/
01403 void sciDrawFigure( int numFigure )
01404 {
01405   int curFigure = sciGetNumFigure( sciGetCurrentFigure() ) ;
01406   sciSetUsedWindow( numFigure ) ;
01407   sciDrawObj( sciGetCurrentFigure() ) ;
01408   sciSetUsedWindow( curFigure ) ;
01409 }
01410 /*------------------------------------------------------------------------------------------*/
01411 
01412 /*-------------------------------------------------------------------------------------------*/
01413 /* sciRefreshObj                                                                             */
01414 /* draw an object but before select the rigth figure for display                             */
01415 /*-------------------------------------------------------------------------------------------*/
01416 int sciRefreshObj( sciPointObj * pobj )
01417 {
01418   
01419   int parentId = sciGetNum( sciGetParentFigure( pobj ) ) ;
01420   int currentId             ;
01421   int status                ;
01422   int verboseGet        = 0 ;
01423   int iDontKnowWhatItIs     ;
01424   /* get current Id in ScilabXgc */
01425   C2F (dr) ("xget", "window",&verboseGet,&currentId,&iDontKnowWhatItIs,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
01426 
01427   /* set the parent figure of the object as the current figure */
01428   if ( parentId != currentId )
01429   {
01430     C2F (dr) ("xset", "window",&parentId,PI0,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
01431   }
01432   
01433   /* draw the object */
01434   status = sciDrawObjIfRequired( pobj ) ;
01435 
01436   /* set back the values */
01437   if ( parentId != currentId )
01438   {
01439     C2F (dr) ("xset", "window",&currentId,PI0,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
01440   }
01441 
01442   return status ;
01443   
01444   
01445 }
01446 
01447 
01448 
01456 int
01457 sciDrawObjIfRequired (sciPointObj * pobj)
01458 {
01459   sciPointObj * pfigure = sciGetParentFigure(pobj);
01460 
01461   if( pFIGURE_FEATURE(pfigure)->auto_redraw && pFIGURE_FEATURE(pfigure)->visible )
01462   {
01463     sciDrawObj(pobj);
01464   }
01465 
01466   return 0;
01467 }
01468 
01474 int
01475 sciDrawObj (sciPointObj * pobj)
01476 {
01477  
01478   
01479   /* driver test */  
01480   if((GetDriverId() != 0) && ( isGraphicSessionOpened() )){
01481     return -1;
01482   }
01483 
01484   switch (sciGetEntityType (pobj))
01485     {
01486     case SCI_FIGURE:
01487       return drawFigureEntity( pobj ) ;
01488       break;
01489     case SCI_SUBWIN:
01490       return drawSubWinEntity( pobj ) ;
01491       break ;
01492     case SCI_AGREG:
01493       return drawCompoundEntity( pobj ) ;
01494       break;
01495     case SCI_LEGEND:
01496       return drawLegendEntity( pobj ) ;
01497       break;   
01498     case SCI_FEC:
01499       return drawFecEntity( pobj ) ;
01500       break;      
01501     case SCI_SEGS:
01502       return drawSegsEntity( pobj ) ;
01503       break;
01504     case SCI_GRAYPLOT:
01505       return drawGrayplotEntity( pobj ) ;
01506       break;
01507     case SCI_POLYLINE:   
01508       return drawPolylineEntity( pobj ) ;
01509       break;
01510     case SCI_ARC:
01511       return drawArcEntity( pobj ) ;
01512       break;
01513     case SCI_RECTANGLE:
01514       return drawRectangleEntity( pobj ) ;
01515       break;
01516     case SCI_TEXT:
01517       return drawTextEntity( pobj ) ;
01518       break;
01519     case SCI_AXES:
01520       return drawAxesEntity(pobj) ;
01521       break;
01522     case SCI_MERGE:
01523       return drawMergeEntity(pobj) ;
01524       break ;
01525     case SCI_SURFACE:
01526       return drawSurfaceEntity(pobj) ;
01527       break;
01528     case SCI_LIGHT:
01529     case SCI_PANNER:
01530     case SCI_SBH:
01531     case SCI_SBV:
01532     case SCI_MENU:
01533     case SCI_MENUCONTEXT:
01534     case SCI_STATUSB:
01535     default:
01536       return -1;
01537       break;
01538     }
01539   /*sciSetSelectedSubWin (curSubWin);*/
01540   return -1;
01541 }
01542 
01543 
01544 
01545 
01546 /* F.Leray 25.02.05 */
01547 /* This function is used to determine how the pixel data*/
01548 /* is given to Xt method (like XDrawLines) */
01549 /* 0 : pixel itself */
01550 /* 1 : pixel's interval */
01551 /* Explanation :*/
01552 /* i.e.in X11 (same thing using Win32 driver), with x2=x1+1 and y1=y2, we have : */
01553 /*   XDrawLine(x1,y1,x1,y1)  does nothing (no pixel lit) */
01554 /*   XDrawLine(x1,y1,x2,y2)  ONE pixel lit */
01555 /* BUT the corresponding function with driver Gif (and others?) give us: */
01556 /* for now (and only for marks), I make a trick using a pixel_offset set to 0 or 1 */
01557 /* depending on the driver. */
01558 
01559 /* slight modif from Bruno : if fact GetDriverId return also 0 */
01560 /* if gtk is enable so I have added a call to withgtk to get the */
01561 /* the good pixel_offset */
01562 
01563 
01564 
01565 int AdaptGraduationsOnYBottomLeft(int iof, int x, int y, int size, integer *Ticsdir, int *fontid, sciPointObj * psubwin, double yminval, double ymaxval, double fx, double fy, double fz)
01566 {
01567   int i;
01568   int nbtics, nbsubtics;
01569   int lastyindex;
01570   int old_rect[4];
01571   int nb_grads_max = 0;
01572   int vx[2], vy[2];
01573   int xm, ym;
01574   double grads_tmp[20];
01575   char c_format[5];
01576   integer barlengthx = 0,barlengthy = 0;
01577   integer rect[4],posi[2];
01578   integer textcolor = -1;
01579   int logrect[4] ;
01580   int XX = 0 ;
01581   int YY = 0 ;
01582   int pas;
01583   double fact_h = 1.5, fact_w = 1.5;
01584   int compteur = 0;
01585 
01586   int possible_pas, possible_compteur;
01587   
01588   sciSubWindow * ppsubwin = pSUBWIN_FEATURE(psubwin);
01589   
01590   for(i=0;i<4;i++) { old_rect[i] = 0 ; } /* Init. old_rect to force first grad. to be displayed */
01591   
01592   lastyindex = ppsubwin->axes.nygrads - 1;
01593   
01594   if(lastyindex == 0)
01595     ChooseFormatForOneGrad(c_format,&(ppsubwin->axes.ygrads[0]));
01596   else
01597     ChoixFormatE(c_format,
01598                  ppsubwin->axes.ygrads[0],
01599                  ppsubwin->axes.ygrads[lastyindex],
01600                  ((ppsubwin->axes.ygrads[lastyindex])-(ppsubwin->axes.ygrads[0]))/(lastyindex));
01601   
01602   nbtics = ppsubwin->axes.nygrads;
01603   nbsubtics = ppsubwin->axes.nbsubtics[1];
01604   
01605   
01606   for(i=0;i<nbtics;i++) grads_tmp[i] = ppsubwin->axes.ygrads[i];
01607 
01608   for(i=0;i<nbtics;i++)
01609     {
01610       char foo[256];
01611       double ytmp = ppsubwin->axes.ygrads[i];
01612                   
01613                   
01614       sprintf(foo,c_format,ytmp);
01615 
01616       /***************************************************************/
01617       /************************* COMMON PART *************************/
01618       /***************************************************************/
01619       if(ppsubwin->axes.reverse[1] == TRUE)
01620         ytmp = InvAxis(ppsubwin->FRect[1],ppsubwin->FRect[3],ytmp);
01621                   
01622       ComputeGoodTrans3d(psubwin,1,&xm,&ym,&fx,&ytmp,&fz);
01623                   
01624       vx[0]=xm;vy[0]=ym;
01625                   
01626       barlengthx= (integer) (( Ticsdir[0])/sqrt((double) Ticsdir[0]*Ticsdir[0]+Ticsdir[1]*Ticsdir[1])*size);
01627       barlengthy= (integer) (( Ticsdir[1])/sqrt((double) Ticsdir[0]*Ticsdir[0]+Ticsdir[1]*Ticsdir[1])*size);
01628 
01629       C2F(dr)("xset","font",fontid,fontid+1,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L); /* fix bug noticed by R.N. */
01630       C2F(dr)("xstringl",foo,&x,&y,rect,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
01631                       
01632       
01633       if (IsDownAxes(psubwin)){
01634         vx[1]=vx[0];
01635         vy[1]=vy[0]+iof/2;
01636         posi[0] = inint(xm-rect[2]/2);
01637         posi[1]=inint( vy[0] + iof + rect[3]);}
01638       else{
01639         vx[1]=vx[0]+barlengthx;
01640         vy[1]=vy[0]+barlengthy;
01641         posi[0] = inint( xm+2*barlengthx-rect[2]);
01642         posi[1]=inint( ym + 2*barlengthy + rect[3]);}
01643       
01644       /* compute bounding of "10"  string used for log scale ON and auto_ticks ON */
01645       C2F(dr)("xstringl","10",&XX,&YY,logrect,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
01646       
01647       
01648       if(CheckDisplay(fact_h, fact_w, ppsubwin->logflags[1],foo,posi,fontid,old_rect) == 0)
01649         continue; /*  graduation too close, DO NOT display the graduation ! */
01650       
01651       
01652       C2F(dr)("xset","pattern",&textcolor,PI0,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
01653       C2F(dr)("xset","font",fontid,fontid+1,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
01654       if ( ppsubwin->logflags[1] == 'l' )
01655         {
01656           int smallersize = fontid[1]-2;
01657           int old_rect10[4];
01658           int posi10[2];
01659 
01660           posi10[0] = posi[0] - logrect[2];
01661           posi10[1] = posi[1] + logrect[3];
01662           
01663           C2F(dr)("xset","font",fontid,fontid+1,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
01664           
01665           C2F(dr)("xstringl","10",(&posi10[0]),(&posi10[1]),old_rect10,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
01666           
01667           posi[0] = old_rect10[0] + old_rect10[2];
01668           posi[1] = (int) (old_rect10[1] - old_rect10[3]*.1);
01669           
01670           C2F(dr)("xset","font",fontid,&smallersize,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
01671           C2F(dr)("xstringl",foo,(&posi[0]),(&posi[1]),old_rect,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
01672           
01673           /* update old_rect */
01674           old_rect[2] = (int)(fact_w*(old_rect[2] + (double)old_rect10[2]));
01675           old_rect[3] = (int)(fact_h*(old_rect[3] + old_rect10[3] + (int) (old_rect10[3]*.1)));
01676           old_rect[0] = old_rect10[0];
01677           old_rect[1] = old_rect[1];
01678           
01679           nb_grads_max++;
01680           
01681           /* put back the current fontid */
01682           C2F(dr)("xset","font",fontid,fontid+1,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
01683         }
01684       else{
01685         /* update old_rect */
01686         C2F(dr)("xstringl",foo,(&posi[0]),(&posi[1]),old_rect,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
01687         old_rect[3] = (int)(fact_h* old_rect[3]);
01688         old_rect[2] = (int)(fact_w* old_rect[2]);
01689         nb_grads_max++;
01690       }
01691     }
01692   
01693   if(ppsubwin->logflags[1] != 'l')
01694     if(nb_grads_max == 1) /* only one grad. can be displayed : we choose to display the average value (max+min)/2 */
01695       {
01696         ppsubwin->axes.ygrads[0] = (grads_tmp[0]+grads_tmp[lastyindex])/2.;
01697         ppsubwin->axes.nygrads = 1;
01698         
01699         if ( !ppsubwin->flagNax )
01700         {
01701           /* don't change the number if it aldready has been specified */
01702           ppsubwin->axes.nbsubtics[1] = 1 ;
01703         }
01704         return 0;
01705       }
01706   
01707   
01708   pas = nbtics - 2; /* pas == grads number - 2 */
01709   
01710   possible_pas = -99;
01711   possible_compteur = -99;
01712   
01713   while(pas > 0)
01714     {
01715       int tmp = 0;
01716       compteur = 0;
01717       for(;;)
01718         {
01719           tmp = tmp + pas;
01720           compteur++;
01721           
01722           if((tmp == (nbtics - 1)) && (compteur < nb_grads_max)){
01723             possible_pas = pas;
01724             possible_compteur = ++compteur;
01725             break;
01726           }
01727           
01728           if(tmp > (nbtics - 1))
01729             break;
01730         }
01731       
01732       pas--;
01733     }
01734   
01735   
01736   if(possible_compteur != -99){
01737     compteur = possible_compteur;
01738     pas = possible_pas;
01739     
01740     for(i=0;i<compteur;i++)
01741       ppsubwin->axes.ygrads[i] = grads_tmp[i*pas];
01742     
01743     ppsubwin->axes.nygrads = compteur;
01744     
01745     /* Nb of subtics computation and storage */
01746     /* jb Silvy 01/2006 : default value was Max((int) abs((13-compteur)/2),2) */
01747     ppsubwin->axes.nbsubtics[1] = ComputeNbSubTicsFor3dUse(psubwin,
01748                                                            ppsubwin->axes.nygrads,
01749                                                            ppsubwin->logflags[1],
01750                                                            ppsubwin->axes.ygrads,
01751                                                            ppsubwin->axes.nbsubtics[1]);
01752   }
01753   else{
01754     ppsubwin->axes.ygrads[0] = grads_tmp[0];
01755     ppsubwin->axes.ygrads[1] = grads_tmp[lastyindex];
01756     ppsubwin->axes.nygrads = 2;
01757     /* Nb of subtics computation and storage */
01758     /* jb Silvy 01/2006 : default value was Max((int) abs((13-compteur)/2),2) */
01759     ppsubwin->axes.nbsubtics[1] = ComputeNbSubTicsFor3dUse(psubwin,
01760                                                            ppsubwin->axes.nygrads,
01761                                                            ppsubwin->logflags[1],
01762                                                            ppsubwin->axes.ygrads,
01763                                                            ppsubwin->axes.nbsubtics[1]);
01764     
01765     if(ppsubwin->logflags[1] == 'n'){
01766       if(nb_grads_max > 4) {
01767         /* we could display at least 4 graduations but we did not find a proper interval... */
01768         /* To avoid to display only the min and max (see above), we add 2 newly created grads by interpolating between min and max */
01769         double pas_ = (grads_tmp[lastyindex]-grads_tmp[0])/3;
01770         for(i=0;i<3;i++){
01771           ppsubwin->axes.ygrads[i] = grads_tmp[0] + i*pas_;
01772         }
01773         
01774         ppsubwin->axes.ygrads[3] = grads_tmp[lastyindex]; /* exact max */
01775         ppsubwin->axes.nygrads = 4;
01776         /* Nb of subtics computation and storage */
01777         ppsubwin->axes.nbsubtics[1] = ComputeNbSubTicsFor3dUse(psubwin,
01778                                                                ppsubwin->axes.nygrads,
01779                                                                'n',
01780                                                                ppsubwin->axes.ygrads,
01781                                                                ppsubwin->axes.nbsubtics[1]);
01782       }
01783     }
01784   }
01785   
01786   return 0;
01787 }
01788 
01789 
01790 int AdaptGraduationsOnXBottomLeft(int iof, int x, int y, int size, integer *Ticsdir, int *fontid, sciPointObj * psubwin, double xminval, double xmaxval, double fx, double fy, double fz)
01791 {
01792   int i;
01793   int nbtics, nbsubtics;
01794   int lastxindex;
01795   int old_rect[4];
01796   int nb_grads_max = 0;
01797   int vx[2], vy[2];
01798   int xm, ym;
01799   double grads_tmp[20];
01800   char c_format[5];
01801   integer barlengthx = 0,barlengthy = 0;
01802   integer rect[4],posi[2]; 
01803   integer textcolor = -1;
01804   int logrect[4],XX,YY;
01805   int pas;
01806   double fact_h = 1.5, fact_w = 1.5;
01807   int compteur = 0;
01808 
01809   int possible_pas, possible_compteur;
01810   
01811   sciSubWindow * ppsubwin = pSUBWIN_FEATURE(psubwin);
01812   
01813   for(i=0;i<4;i++) old_rect[i] = 0; /* Init. old_rect to force first grad. to be displayed */
01814   
01815   lastxindex = ppsubwin->axes.nxgrads - 1;
01816   
01817   if(lastxindex == 0)
01818     ChooseFormatForOneGrad(c_format,&(ppsubwin->axes.xgrads[0]));
01819   else
01820     ChoixFormatE(c_format,
01821                  ppsubwin->axes.xgrads[0],
01822                  ppsubwin->axes.xgrads[lastxindex],
01823                  ((ppsubwin->axes.xgrads[lastxindex])-(ppsubwin->axes.xgrads[0]))/(lastxindex));
01824   
01825   nbtics = ppsubwin->axes.nxgrads;
01826   nbsubtics = ppsubwin->axes.nbsubtics[0];
01827   
01828   
01829   for(i=0;i<nbtics;i++) grads_tmp[i] = ppsubwin->axes.xgrads[i];
01830 
01831   for(i=0;i<nbtics;i++)
01832     {
01833       char foo[256]; 
01834       double xtmp = ppsubwin->axes.xgrads[i];
01835                   
01836       sprintf(foo,c_format,xtmp);
01837 
01838       /***************************************************************/
01839       /************************* COMMON PART *************************/
01840       /***************************************************************/
01841       if(ppsubwin->axes.reverse[0] == TRUE)
01842         xtmp = InvAxis(ppsubwin->FRect[0],ppsubwin->FRect[2],xtmp);
01843                   
01844       ComputeGoodTrans3d(psubwin,1,&xm,&ym,&xtmp,&fy,&fz);
01845                   
01846       vx[0]=xm;vy[0]=ym; 
01847                   
01848       barlengthx= (integer) (( Ticsdir[0])/sqrt((double) Ticsdir[0]*Ticsdir[0]+Ticsdir[1]*Ticsdir[1])*size);
01849       barlengthy= (integer) (( Ticsdir[1])/sqrt((double) Ticsdir[0]*Ticsdir[0]+Ticsdir[1]*Ticsdir[1])*size);
01850 
01851       C2F(dr)("xset","font",fontid,fontid+1,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L); /* fix bug noticed by R.N. */
01852       C2F(dr)("xstringl",foo,&x,&y,rect,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
01853       
01854 
01855       if (IsDownAxes(psubwin)){
01856         vx[1]=vx[0];
01857         vy[1]=vy[0]+iof/2;
01858         posi[0] = inint(xm-rect[2]/2); 
01859         posi[1]=inint( vy[0] + iof + rect[3]);}
01860       else{
01861         vx[1]=vx[0]+barlengthx;
01862         vy[1]=vy[0]+barlengthy;
01863         posi[0] = inint( xm+2*barlengthx-rect[2]); 
01864         posi[1]=inint( ym + 2*barlengthy + rect[3]);}
01865       
01866       /* compute bounding of "10"  string used for log scale ON and auto_ticks ON */
01867       C2F(dr)("xstringl","10",&XX,&YY,logrect,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);       
01868       
01869       
01870       if(CheckDisplay(fact_h, fact_w, ppsubwin->logflags[0],foo,posi,fontid,old_rect) == 0)
01871         continue; /*  graduation too close, DO NOT display the graduation ! */
01872       
01873       
01874       C2F(dr)("xset","pattern",&textcolor,PI0,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
01875       C2F(dr)("xset","font",fontid,fontid+1,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
01876       if ( ppsubwin->logflags[0] == 'l' )
01877         {
01878           int smallersize = fontid[1]-2;
01879           int old_rect10[4];
01880           int posi10[2];
01881 
01882           posi10[0] = posi[0] - logrect[2];
01883           posi10[1] = posi[1] + logrect[3];
01884           
01885           C2F(dr)("xset","font",fontid,fontid+1,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
01886           
01887           C2F(dr)("xstringl","10",(&posi10[0]),(&posi10[1]),old_rect10,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
01888           
01889           posi[0] = old_rect10[0] + old_rect10[2];
01890           posi[1] = (int) (old_rect10[1] - old_rect10[3]*.1);
01891           
01892           C2F(dr)("xset","font",fontid,&smallersize,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
01893           C2F(dr)("xstringl",foo,(&posi[0]),(&posi[1]),old_rect,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
01894           
01895           /* update old_rect */
01896           old_rect[2] = (int)(fact_w*(old_rect[2] + old_rect10[2]));
01897           old_rect[3] = (int)(fact_h*(old_rect[3] + old_rect10[3] + (int) (old_rect10[3]*.1)));
01898           old_rect[0] = old_rect10[0];
01899           old_rect[1] = old_rect[1];
01900           
01901           nb_grads_max++;
01902           
01903           /* put back the current fontid */
01904           C2F(dr)("xset","font",fontid,fontid+1,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
01905         }
01906       else{
01907         /* update old_rect */
01908         C2F(dr)("xstringl",foo,(&posi[0]),(&posi[1]),old_rect,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
01909         old_rect[3] = (int)(fact_h* old_rect[3]);
01910         old_rect[2] = (int)(fact_w* old_rect[2]);
01911         nb_grads_max++;
01912       }
01913     }
01914   
01915   if(ppsubwin->logflags[0] != 'l')
01916     if(nb_grads_max == 1) /* only one grad. can be displayed : we choose to display the average value (max+min)/2 */
01917       {
01918         ppsubwin->axes.xgrads[0] = (grads_tmp[0]+grads_tmp[lastxindex])/2.;
01919         ppsubwin->axes.nxgrads = 1;
01920         if ( !ppsubwin->flagNax )
01921         {
01922           ppsubwin->axes.nbsubtics[0] = 1;
01923         }
01924         return 0;
01925       }
01926   
01927   
01928   pas = nbtics - 2; /* pas == grads number - 2 */
01929   
01930   possible_pas = -99;
01931   possible_compteur = -99;
01932   
01933   while(pas > 0)
01934     {
01935       int tmp = 0;
01936       compteur = 0;
01937       for(;;)
01938         {
01939           tmp = tmp + pas;
01940           compteur++;
01941           
01942           if((tmp == (nbtics - 1)) && (compteur < nb_grads_max)){
01943             possible_pas = pas;
01944             possible_compteur = ++compteur;
01945             break;
01946           }
01947           
01948           if(tmp > (nbtics - 1))
01949             break;
01950         }
01951       
01952       pas--;
01953     }
01954   
01955   
01956   if(possible_compteur != -99){
01957     compteur = possible_compteur;
01958     pas = possible_pas;
01959     
01960     for(i=0;i<compteur;i++)
01961       ppsubwin->axes.xgrads[i] = grads_tmp[i*pas];
01962     
01963     ppsubwin->axes.nxgrads = compteur;
01964     
01965     /* Nb of subtics computation and storage */
01966     /* jb Silvy 01/2006 : default value was Max((int) abs((13-compteur)/2),2) */
01967     ppsubwin->axes.nbsubtics[0] = ComputeNbSubTicsFor3dUse(psubwin,
01968                                                            ppsubwin->axes.nxgrads,
01969                                                            ppsubwin->logflags[0],
01970                                                            ppsubwin->axes.xgrads,
01971                                                            ppsubwin->axes.nbsubtics[0]); 
01972   }
01973   else{
01974     ppsubwin->axes.xgrads[0] = grads_tmp[0];
01975     ppsubwin->axes.xgrads[1] = grads_tmp[lastxindex];
01976     ppsubwin->axes.nxgrads = 2;
01977     /* Nb of subtics computation and storage */
01978     /* jb Silvy 01/2006 : default value was Max((int) abs((13-compteur)/2),2) */
01979     ppsubwin->axes.nbsubtics[0] = ComputeNbSubTicsFor3dUse(psubwin,
01980                                                            ppsubwin->axes.nxgrads,
01981                                                            ppsubwin->logflags[0],
01982                                                            ppsubwin->axes.xgrads,
01983                                                            ppsubwin->axes.nbsubtics[0]); 
01984     
01985     if(ppsubwin->logflags[0] == 'n'){
01986       if(nb_grads_max > 4) {
01987         /* we could display at least 4 graduations but we did not find a proper interval... */
01988         /* To avoid to display only the min and max (see above), we add 2 newly created grads by interpolating between min and max */
01989         double pas_ = (grads_tmp[lastxindex]-grads_tmp[0])/3;
01990         for(i=0;i<3;i++){
01991           ppsubwin->axes.xgrads[i] = grads_tmp[0] + i*pas_;
01992         }
01993         
01994         ppsubwin->axes.xgrads[3] = grads_tmp[lastxindex]; /* exact max */
01995         ppsubwin->axes.nxgrads = 4;
01996         
01997         /* Nb of subtics computation and storage */
01998         /* jb Silvy 01/2006 : default value was Max((int) abs((13-compteur)/2),2) */
01999         ppsubwin->axes.nbsubtics[0] = ComputeNbSubTicsFor3dUse(psubwin,
02000                                                                ppsubwin->axes.nxgrads,
02001                                                                'n',
02002                                                                ppsubwin->axes.xgrads,
02003                                                                ppsubwin->axes.nbsubtics[0]); 
02004       }
02005     }
02006   }
02007   
02008   return 0;
02009 }
02010 
02011 
02012 
02013 int AdaptGraduationsOnYBottomRight(int iof, int x, int y, int size, integer *Ticsdir, int *fontid, sciPointObj * psubwin, double yminval, double ymaxval, double fx, double fy, double fz)
02014 {
02015   int i;
02016   int nbtics, nbsubtics;
02017   int lastyindex;
02018   int old_rect[4];
02019   int nb_grads_max = 0;
02020   int vx[2], vy[2];
02021   int xm, ym;
02022   double grads_tmp[20];
02023   char c_format[5];
02024   integer barlengthx = 0,barlengthy = 0;
02025   integer rect[4],posi[2]; 
02026   integer textcolor = -1;
02027   int logrect[4] ;
02028   int XX = 0 ;
02029   int YY = 0 ;
02030   int pas;
02031   double fact_h = 1.5, fact_w = 1.5;
02032   int compteur = 0;
02033 
02034   int possible_pas, possible_compteur;
02035   
02036   sciSubWindow * ppsubwin = pSUBWIN_FEATURE(psubwin);
02037   
02038   for(i=0;i<4;i++) old_rect[i] = 0; /* Init. old_rect to force first grad. to be displayed */
02039   
02040   lastyindex = ppsubwin->axes.nygrads - 1;
02041   
02042   if(lastyindex == 0)
02043     ChooseFormatForOneGrad(c_format,&(ppsubwin->axes.ygrads[0]));
02044   else
02045     ChoixFormatE(c_format,
02046                  ppsubwin->axes.ygrads[0],
02047                  ppsubwin->axes.ygrads[lastyindex],
02048                  ((ppsubwin->axes.ygrads[lastyindex])-(ppsubwin->axes.ygrads[0]))/(lastyindex));
02049   
02050   nbtics = ppsubwin->axes.nygrads;
02051   nbsubtics = ppsubwin->axes.nbsubtics[1];
02052   
02053   
02054   for(i=0;i<nbtics;i++) grads_tmp[i] = ppsubwin->axes.ygrads[i];
02055 
02056   for(i=0;i<nbtics;i++)
02057     {
02058       char foo[256]; 
02059       double ytmp = ppsubwin->axes.ygrads[i];
02060                   
02061       sprintf(foo,c_format,ytmp);
02062 
02063       /***************************************************************/
02064       /************************* COMMON PART *************************/
02065       /***************************************************************/
02066       if(ppsubwin->axes.reverse[1] == TRUE)
02067         ytmp = InvAxis(ppsubwin->FRect[1],ppsubwin->FRect[3],ytmp);
02068                   
02069       ComputeGoodTrans3d(psubwin,1,&xm,&ym,&fx,&ytmp,&fz);
02070                   
02071       vx[0]=xm;vy[0]=ym; 
02072                   
02073       barlengthx= (integer) (( Ticsdir[0])/sqrt((double) Ticsdir[0]*Ticsdir[0]+Ticsdir[1]*Ticsdir[1])*size);
02074       barlengthy= (integer) (( Ticsdir[1])/sqrt((double) Ticsdir[0]*Ticsdir[0]+Ticsdir[1]*Ticsdir[1])*size);
02075 
02076       C2F(dr)("xset","font",fontid,fontid+1,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L); /* fix bug noticed by R.N. */
02077       C2F(dr)("xstringl",foo,&x,&y,rect,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
02078       
02079 
02080       if (IsDownAxes(psubwin)){
02081         vx[1]=vx[0];
02082         vy[1]=vy[0]+iof/2;
02083         posi[0] = inint(xm-rect[2]/2); 
02084         posi[1]=inint( vy[0] + iof + rect[3]);}
02085       else{
02086         vx[1]=vx[0]+barlengthx;
02087         vy[1]=vy[0]+barlengthy;
02088         posi[0] = inint( xm+2*barlengthx);
02089         posi[1]=inint( ym + 2*barlengthy + rect[3]);}
02090                       
02091       
02092       /* compute bounding of "10"  string used for log scale ON and auto_ticks ON */
02093       C2F(dr)("xstringl","10",&XX,&YY,logrect,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);       
02094       
02095       
02096       if(CheckDisplay(fact_h, fact_w, ppsubwin->logflags[1],foo,posi,fontid,old_rect) == 0)
02097         continue; /*  graduation too close, DO NOT display the graduation ! */
02098       
02099       
02100       C2F(dr)("xset","pattern",&textcolor,PI0,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
02101       C2F(dr)("xset","font",fontid,fontid+1,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
02102       if ( ppsubwin->logflags[1] == 'l' )
02103         {
02104           int smallersize = fontid[1]-2;
02105           int old_rect10[4];
02106           int posi10[2];
02107 
02108           posi10[0] = posi[0] - logrect[2];
02109           posi10[1] = posi[1] + logrect[3];
02110           
02111           C2F(dr)("xset","font",fontid,fontid+1,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
02112           
02113           C2F(dr)("xstringl","10",(&posi10[0]),(&posi10[1]),old_rect10,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
02114           
02115           posi[0] = old_rect10[0] + old_rect10[2];
02116           posi[1] = (int) (old_rect10[1] - old_rect10[3]*.1);
02117           
02118           C2F(dr)("xset","font",fontid,&smallersize,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
02119           C2F(dr)("xstringl",foo,(&posi[0]),(&posi[1]),old_rect,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
02120           
02121           /* update old_rect */
02122           old_rect[2] = (int)(fact_w*(old_rect[2] + old_rect10[2]));
02123           old_rect[3] = (int)(fact_h*(old_rect[3] + old_rect10[3] + (int) (old_rect10[3]*.1)));
02124           old_rect[0] = old_rect10[0];
02125           old_rect[1] = old_rect[1];
02126           
02127           nb_grads_max++;
02128           
02129           /* put back the current fontid */
02130           C2F(dr)("xset","font",fontid,fontid+1,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
02131         }
02132       else{
02133         /* update old_rect */
02134         C2F(dr)("xstringl",foo,(&posi[0]),(&posi[1]),old_rect,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
02135         old_rect[3] = (int)(fact_h* old_rect[3]);
02136         old_rect[2] = (int)(fact_w* old_rect[2]);
02137         nb_grads_max++;
02138       }
02139     }
02140   
02141   if(ppsubwin->logflags[1] != 'l')
02142     if(nb_grads_max == 1) /* only one grad. can be displayed : we choose to display the average value (max+min)/2 */
02143       {
02144         ppsubwin->axes.ygrads[0] = (grads_tmp[0]+grads_tmp[lastyindex])/2.;
02145         ppsubwin->axes.nygrads = 1;
02146         if ( !ppsubwin->flagNax )
02147         {
02148           ppsubwin->axes.nbsubtics[1] = 1;
02149         }
02150         return 0;
02151       }
02152   
02153   
02154   pas = nbtics - 2; /* pas == grads number - 2 */
02155   
02156   possible_pas = -99;
02157   possible_compteur = -99;
02158   
02159   while(pas > 0)
02160     {
02161       int tmp = 0;
02162       compteur = 0;
02163       for(;;)
02164         {
02165           tmp = tmp + pas;
02166           compteur++;
02167           
02168           if((tmp == (nbtics - 1)) && (compteur < nb_grads_max)){
02169             possible_pas = pas;
02170             possible_compteur = ++compteur;
02171             break;
02172           }
02173           
02174           if(tmp > (nbtics - 1))
02175             break;
02176         }
02177       
02178       pas--;
02179     }
02180   
02181   
02182   if(possible_compteur != -99){
02183     compteur = possible_compteur;
02184     pas = possible_pas;
02185     
02186     for(i=0;i<compteur;i++)
02187       ppsubwin->axes.ygrads[i] = grads_tmp[i*pas];
02188     
02189     ppsubwin->axes.nygrads = compteur;
02190     
02191     /* Nb of subtics computation and storage */
02192     /* jb Silvy 01/2006 : default value was Max((int) abs((13-compteur)/2),2) */
02193     ppsubwin->axes.nbsubtics[1] = ComputeNbSubTicsFor3dUse(psubwin,
02194                                                            ppsubwin->axes.nygrads,
02195                                                            ppsubwin->logflags[1],
02196                                                            ppsubwin->axes.ygrads,
02197                                                            ppsubwin->axes.nbsubtics[1]);
02198   }
02199   else{
02200     ppsubwin->axes.ygrads[0] = grads_tmp[0];
02201     ppsubwin->axes.ygrads[1] = grads_tmp[lastyindex];
02202     ppsubwin->axes.nygrads = 2;
02203 
02204     /* Nb of subtics computation and storage */
02205     /* jb Silvy 01/2006 : default value was Max((int) abs((13-compteur)/2),2) */
02206     ppsubwin->axes.nbsubtics[1] = ComputeNbSubTicsFor3dUse(psubwin,
02207                                                            ppsubwin->axes.nygrads,
02208                                                            ppsubwin->logflags[1],
02209                                                            ppsubwin->axes.ygrads,
02210                                                            ppsubwin->axes.nbsubtics[1]);
02211     
02212     if(ppsubwin->logflags[1] == 'n'){
02213       if(nb_grads_max > 4) {
02214         /* we could display at least 4 graduations but we did not find a proper interval... */
02215         /* To avoid to display only the min and max (see above), we add 2 newly created grads by interpolating between min and max */
02216         double pas_ = (grads_tmp[lastyindex]-grads_tmp[0])/3;
02217         for(i=0;i<3;i++){
02218           ppsubwin->axes.ygrads[i] = grads_tmp[0] + i*pas_;
02219         }
02220         
02221         ppsubwin->axes.ygrads[3] = grads_tmp[lastyindex]; /* exact max */
02222         ppsubwin->axes.nygrads = 4;
02223         /* Nb of subtics computation and storage */
02224         /* jb Silvy 01/2006 : default value was Max((int) abs((13-compteur)/2),2) */
02225         ppsubwin->axes.nbsubtics[1] = ComputeNbSubTicsFor3dUse(psubwin,
02226                                                                ppsubwin->axes.nygrads,
02227                                                                'n',
02228                                                                ppsubwin->axes.ygrads,
02229                                                                ppsubwin->axes.nbsubtics[1]);
02230       }
02231     }
02232   }
02233   
02234   return 0;
02235 }
02236 
02237 
02238 int AdaptGraduationsOnXBottomRight(int iof, int x, int y, int size, integer *Ticsdir, int *fontid, sciPointObj * psubwin, double xminval, double xmaxval, double fx, double fy, double fz)
02239 {
02240   int i;
02241   int nbtics, nbsubtics;
02242   int lastxindex;
02243   int old_rect[4];
02244   int nb_grads_max = 0;
02245   int vx[2], vy[2];
02246   int xm, ym;
02247   double grads_tmp[20];
02248   char c_format[5];
02249   integer barlengthx = 0,barlengthy = 0;
02250   integer rect[4],posi[2]; 
02251   integer textcolor = -1;
02252   int logrect[4] ;
02253   int XX = 0;
02254   int YY = 0 ;
02255   int pas;
02256   double fact_h = 1.5, fact_w = 1.5;
02257   int compteur = 0;
02258 
02259   int possible_pas, possible_compteur;
02260   
02261   sciSubWindow * ppsubwin = pSUBWIN_FEATURE(psubwin);
02262   
02263   for(i=0;i<4;i++) old_rect[i] = 0; /* Init. old_rect to force first grad. to be displayed */
02264   
02265   lastxindex = ppsubwin->axes.nxgrads - 1;
02266   
02267   if(lastxindex == 0)
02268     ChooseFormatForOneGrad(c_format,&(ppsubwin->axes.xgrads[0]));
02269   else
02270     ChoixFormatE(c_format,
02271                  ppsubwin->axes.xgrads[0],
02272                  ppsubwin->axes.xgrads[lastxindex],
02273                  ((ppsubwin->axes.xgrads[lastxindex])-(ppsubwin->axes.xgrads[0]))/(lastxindex));
02274   
02275   nbtics = ppsubwin->axes.nxgrads;
02276   nbsubtics = ppsubwin->axes.nbsubtics[0];
02277   
02278   
02279   for(i=0;i<nbtics;i++) grads_tmp[i] = ppsubwin->axes.xgrads[i];
02280 
02281   for(i=0;i<nbtics;i++)
02282     {
02283       char foo[256]; 
02284       double xtmp = ppsubwin->axes.xgrads[i];
02285                   
02286       sprintf(foo,c_format,xtmp);
02287 
02288       /***************************************************************/
02289       /************************* COMMON PART *************************/
02290       /***************************************************************/
02291       if(ppsubwin->axes.reverse[0] == TRUE)
02292         xtmp = InvAxis(ppsubwin->FRect[0],ppsubwin->FRect[2],xtmp);
02293                   
02294       ComputeGoodTrans3d(psubwin,1,&xm,&ym,&xtmp,&fy,&fz);
02295                   
02296       vx[0]=xm;vy[0]=ym; 
02297                   
02298       barlengthx= (integer) (( Ticsdir[0])/sqrt((double) Ticsdir[0]*Ticsdir[0]+Ticsdir[1]*Ticsdir[1])*size);
02299       barlengthy= (integer) (( Ticsdir[1])/sqrt((double) Ticsdir[0]*Ticsdir[0]+Ticsdir[1]*Ticsdir[1])*size);
02300 
02301       C2F(dr)("xset","font",fontid,fontid+1,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L); /* fix bug noticed by R.N. */
02302       C2F(dr)("xstringl",foo,&x,&y,rect,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
02303       
02304 
02305       if (IsDownAxes(psubwin)){
02306         vx[1]=vx[0];
02307         vy[1]=vy[0]+iof/2;
02308         posi[0] = inint(xm-rect[2]/2); 
02309         posi[1]=inint( vy[0] + iof + rect[3]);}
02310       else{
02311         vx[1]=vx[0]+barlengthx;
02312         vy[1]=vy[0]+barlengthy;
02313         posi[0] = inint( xm+2*barlengthx);
02314         posi[1]=inint( ym + 2*barlengthy + rect[3]);}
02315                       
02316       
02317       /* compute bounding of "10"  string used for log scale ON and auto_ticks ON */
02318       C2F(dr)("xstringl","10",&XX,&YY,logrect,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);       
02319       
02320       
02321       if(CheckDisplay(fact_h, fact_w, ppsubwin->logflags[0],foo,posi,fontid,old_rect) == 0)
02322         continue; /*  graduation too close, DO NOT display the graduation ! */
02323       
02324       
02325       C2F(dr)("xset","pattern",&textcolor,PI0,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
02326       C2F(dr)("xset","font",fontid,fontid+1,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
02327       if ( ppsubwin->logflags[0] == 'l' )
02328         {
02329           int smallersize = fontid[1]-2;
02330           int old_rect10[4];
02331           int posi10[2];
02332 
02333           posi10[0] = posi[0] - logrect[2];
02334           posi10[1] = posi[1] + logrect[3];
02335           
02336           C2F(dr)("xset","font",fontid,fontid+1,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
02337           
02338           C2F(dr)("xstringl","10",(&posi10[0]),(&posi10[1]),old_rect10,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
02339           
02340           posi[0] = old_rect10[0] + old_rect10[2];
02341           posi[1] = (int) (old_rect10[1] - old_rect10[3]*.1);
02342           
02343           C2F(dr)("xset","font",fontid,&smallersize,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
02344           C2F(dr)("xstringl",foo,(&posi[0]),(&posi[1]),old_rect,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
02345           
02346           /* update old_rect */
02347           old_rect[2] = (int)(fact_w*(old_rect[2] + old_rect10[2]));
02348           old_rect[3] = (int)(fact_h*(old_rect[3] + old_rect10[3] + (int) (old_rect10[3]*.1)));
02349           old_rect[0] = old_rect10[0];
02350           old_rect[1] = old_rect[1];
02351           
02352           nb_grads_max++;
02353           
02354           /* put back the current fontid */
02355           C2F(dr)("xset","font",fontid,fontid+1,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
02356         }
02357       else{
02358         /* update old_rect */
02359         C2F(dr)("xstringl",foo,(&posi[0]),(&posi[1]),old_rect,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
02360         old_rect[3] = (int)(fact_h* old_rect[3]);
02361         old_rect[2] = (int)(fact_w* old_rect[2]);
02362         nb_grads_max++;
02363       }
02364     }
02365   
02366   if(ppsubwin->logflags[0] != 'l')
02367     if(nb_grads_max == 1) /* only one grad. can be displayed : we choose to display the average value (max+min)/2 */
02368       {
02369         ppsubwin->axes.xgrads[0] = (grads_tmp[0]+grads_tmp[lastxindex])/2.;
02370         ppsubwin->axes.nxgrads = 1;
02371         if ( !ppsubwin->flagNax )
02372         {
02373           ppsubwin->axes.nbsubtics[0] = 1;
02374         }
02375         return 0;
02376       }
02377   
02378   
02379   pas = nbtics - 2; /* pas == grads number - 2 */
02380   
02381   possible_pas = -99;
02382   possible_compteur = -99;
02383   
02384   while(pas > 0)
02385     {
02386       int tmp = 0;
02387       compteur = 0;
02388       for(;;)
02389         {
02390           tmp = tmp + pas;
02391           compteur++;
02392           
02393           if((tmp == (nbtics - 1)) && (compteur < nb_grads_max)){
02394             possible_pas = pas;
02395             possible_compteur = ++compteur;
02396             break;
02397           }
02398           
02399           if(tmp > (nbtics - 1))
02400             break;
02401         }
02402       
02403       pas--;
02404     }
02405   
02406   
02407   if(possible_compteur != -99){
02408     compteur = possible_compteur;
02409     pas = possible_pas;
02410     
02411     for(i=0;i<compteur;i++)
02412       ppsubwin->axes.xgrads[i] = grads_tmp[i*pas];
02413     
02414     ppsubwin->axes.nxgrads = compteur;
02415     
02416     ppsubwin->axes.nbsubtics[0] = ComputeNbSubTicsFor3dUse(psubwin,
02417                                                            ppsubwin->axes.nxgrads,
02418                                                            ppsubwin->logflags[0],
02419                                                            ppsubwin->axes.xgrads,
02420                                                            ppsubwin->axes.nbsubtics[0]);
02421   }
02422   else{
02423     ppsubwin->axes.xgrads[0] = grads_tmp[0];
02424     ppsubwin->axes.xgrads[1] = grads_tmp[lastxindex];
02425     ppsubwin->axes.nxgrads = 2;
02426     ppsubwin->axes.nbsubtics[0] = ComputeNbSubTicsFor3dUse(psubwin,
02427                                                            ppsubwin->axes.nxgrads,
02428                                                            ppsubwin->logflags[0],
02429                                                            ppsubwin->axes.xgrads,
02430                                                            ppsubwin->axes.nbsubtics[0]);
02431     if(ppsubwin->logflags[0] == 'n'){
02432       if(nb_grads_max > 4) {
02433         /* we could display at least 4 graduations but we did not find a proper interval... */
02434         /* To avoid to display only the min and max (see above), we add 2 newly created grads by interpolating between min and max */
02435         double pas_ = (grads_tmp[lastxindex]-grads_tmp[0])/3;
02436         for(i=0;i<3;i++){
02437           ppsubwin->axes.xgrads[i] = grads_tmp[0] + i*pas_;
02438         }
02439         
02440         ppsubwin->axes.xgrads[3] = grads_tmp[lastxindex]; /* exact max */
02441         ppsubwin->axes.nxgrads = 4;
02442         ppsubwin->axes.nbsubtics[0] = ComputeNbSubTicsFor3dUse(psubwin,
02443                                                                ppsubwin->axes.nxgrads,
02444                                                                'n',
02445                                                                ppsubwin->axes.xgrads,
02446                                                                ppsubwin->axes.nbsubtics[0] );
02447       }
02448     }
02449   }
02450   
02451   return 0;
02452 }
02453 
02454 int AdaptGraduationsOnZ(int x, int y, int size, integer *Ticsdir, int *fontid, sciPointObj * psubwin, double zminval, double zmaxval, double fx, double fy, double fz)
02455 {
02456   int i;
02457   int nbtics, nbsubtics;
02458   int lastzindex;
02459   int old_rect[4];
02460   int nb_grads_max = 0;
02461   int vx[2], vy[2];
02462   int xm, ym;
02463   double grads_tmp[20];
02464   char c_format[5];
02465   integer barlengthx = 0,barlengthy = 0;
02466   integer rect[4],posi[2]; 
02467   integer textcolor = -1;
02468   int logrect[4] ;
02469   int XX = 0 ;
02470   int YY = 0 ;
02471   int pas;
02472   double fact_h = 1.5, fact_w = 1.;
02473   int compteur;
02474 
02475   int possible_pas, possible_compteur;
02476   
02477   sciSubWindow * ppsubwin = pSUBWIN_FEATURE(psubwin);
02478   
02479   for(i=0;i<4;i++) old_rect[i] = 0; /* Init. old_rect to force first grad. to be displayed */
02480   
02481 
02482 
02483   lastzindex = ppsubwin->axes.nzgrads - 1;
02484   
02485   if(lastzindex == 0)
02486     ChooseFormatForOneGrad(c_format,&(ppsubwin->axes.zgrads[0]));
02487   else
02488     ChoixFormatE(c_format,
02489                  ppsubwin->axes.zgrads[0],
02490                  ppsubwin->axes.zgrads[lastzindex],
02491                  ((ppsubwin->axes.zgrads[lastzindex])-(ppsubwin->axes.zgrads[0]))/(lastzindex));
02492   
02493   nbtics = ppsubwin->axes.nzgrads;
02494   nbsubtics = ppsubwin->axes.nbsubtics[2];
02495 
02496 
02497   for(i=0;i<nbtics;i++) grads_tmp[i] = ppsubwin->axes.zgrads[i];
02498   
02499   for(i=0;i<nbtics;i++)
02500     {
02501       char foo[256];
02502       double ztmp = ppsubwin->axes.zgrads[i];
02503 
02504       sprintf(foo,c_format,ztmp);
02505       
02506       /***************************************************************/
02507       /************************* COMMON PART *************************/
02508       /***************************************************************/
02509       if(ppsubwin->axes.reverse[2] == TRUE)
02510         ztmp = InvAxis(ppsubwin->FRect[4],ppsubwin->FRect[5],ztmp);
02511       
02512       ComputeGoodTrans3d(psubwin,1,&xm,&ym,&fx,&fy,&ztmp);
02513             
02514       
02515       vx[0]=xm;vy[0]=ym;
02516       
02517       barlengthx= (integer) (( Ticsdir[0])/sqrt((double) Ticsdir[0]*Ticsdir[0]+Ticsdir[1]*Ticsdir[1])*size);
02518       barlengthy= (integer) (( Ticsdir[1])/sqrt((double) Ticsdir[0]*Ticsdir[0]+Ticsdir[1]*Ticsdir[1])*size);
02519       vx[1]=vx[0]+barlengthx;
02520       vy[1]=vy[0]+barlengthy;
02521       
02522       /* foo is set above with sprintf(foo,c_format,xtmp); */
02523               
02524       C2F(dr)("xset","font",fontid,fontid+1,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L); /* fix bug noticed by R.N. */
02525       C2F(dr)("xstringl",foo,&x,&y,rect,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
02526       posi[0] = inint( xm+2*barlengthx - rect[2]); 
02527       posi[1]=inint( ym + 2*barlengthy + rect[3]/2);
02528 
02529 
02530       /* compute bounding of "10"  string used for log scale ON and auto_ticks ON */
02531       C2F(dr)("xstringl","10",&XX,&YY,logrect,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);       
02532       
02533       
02534       if(CheckDisplay(fact_h, fact_w, ppsubwin->logflags[2],foo,posi,fontid,old_rect) == 0)
02535         continue; /*  graduation too close, DO NOT display the graduation ! */
02536               
02537       C2F(dr)("xset","pattern",&textcolor,PI0,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
02538       C2F(dr)("xset","font",fontid,fontid+1,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
02539       if ( ppsubwin->logflags[2] == 'l' )
02540         {
02541           int smallersize = fontid[1]-2;
02542           int old_rect10[4];
02543           int posi10[2];
02544           
02545           posi10[0] = posi[0] - logrect[2];
02546           posi10[1] = posi[1] + logrect[3];
02547           
02548           C2F(dr)("xset","font",fontid,fontid+1,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
02549           
02550           C2F(dr)("xstringl","10",(&posi10[0]),(&posi10[1]),old_rect10,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
02551           
02552           posi[0] = old_rect10[0] + old_rect10[2];
02553           posi[1] = (int) (old_rect10[1] - old_rect10[3]*.1);
02554           
02555           C2F(dr)("xset","font",fontid,&smallersize,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
02556           C2F(dr)("xstringl",foo,(&posi[0]),(&posi[1]),old_rect,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
02557           
02558           /* update old_rect */
02559           old_rect[2] = (int)(fact_w*(old_rect[2] + old_rect10[2]));
02560           old_rect[3] = (int)(fact_h*(old_rect[3] + old_rect10[3] + (int) (old_rect10[3]*.1)));
02561           old_rect[0] = old_rect10[0];
02562           old_rect[1] = old_rect[1];
02563           
02564           nb_grads_max++;
02565           
02566           
02567           /* put back the current fontid */
02568           C2F(dr)("xset","font",fontid,fontid+1,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
02569         }
02570       else{
02571         /* update old_rect */
02572         C2F(dr)("xstringl",foo,(&posi[0]),(&posi[1]),old_rect,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
02573         old_rect[3] = (int)(fact_h* old_rect[3]);
02574         old_rect[2] = (int)(fact_w* old_rect[2]);
02575         nb_grads_max++;
02576       }
02577     }
02578   
02579   
02580   if(ppsubwin->logflags[2] != 'l')
02581     if(nb_grads_max == 1) /* only one grad. can be displayed : we choose to display the average value (max+min)/2 */
02582       {
02583         ppsubwin->axes.zgrads[0] = (grads_tmp[0]+grads_tmp[lastzindex])/2.;
02584         ppsubwin->axes.nzgrads = 1;
02585         if ( !ppsubwin->flagNax )
02586         {
02587           ppsubwin->axes.nbsubtics[2] = 1;
02588         }
02589         return 0;
02590       }
02591   
02592   pas = nbtics - 2; /* pas == grads number - 2 */
02593 
02594   possible_pas = -99;
02595   possible_compteur = -99;
02596 
02597   while(pas > 0)
02598     {
02599       int tmp = 0;
02600       compteur = 0;
02601       for(;;)
02602         {
02603           tmp = tmp + pas;
02604           compteur++;
02605           
02606           if((tmp == (nbtics - 1)) && (compteur < nb_grads_max)){
02607             possible_pas = pas;
02608             possible_compteur = ++compteur;
02609             break;
02610           }
02611           
02612           if(tmp > (nbtics - 1))
02613             break;
02614         }
02615       
02616       pas--;
02617     }
02618   
02619   if(possible_compteur != -99){
02620     compteur = possible_compteur;
02621     pas = possible_pas;
02622     
02623     for(i=0;i<compteur;i++)
02624       ppsubwin->axes.zgrads[i] = grads_tmp[i*pas];
02625     
02626     ppsubwin->axes.nzgrads = compteur;
02627     
02628     /* Nb of subtics computation and storage */
02629     /* jb Silvy 01/2006 : default value was Max((int) abs((13-compteur)/2),2) */
02630     ppsubwin->axes.nbsubtics[2] = ComputeNbSubTicsFor3dUse(psubwin,
02631                                                            ppsubwin->axes.nzgrads,
02632                                                            ppsubwin->logflags[2],
02633                                                            ppsubwin->axes.zgrads,
02634                                                            ppsubwin->axes.nbsubtics[2]); 
02635   }
02636   else{
02637     ppsubwin->axes.zgrads[0] = grads_tmp[0];
02638     ppsubwin->axes.zgrads[1] = grads_tmp[lastzindex];
02639     ppsubwin->axes.nzgrads = 2;
02640     /* Nb of subtics computation and storage */
02641     /* jb Silvy 01/2006 : default value was Max((int) abs((13-compteur)/2),2) */
02642     ppsubwin->axes.nbsubtics[2] = ComputeNbSubTicsFor3dUse(psubwin,
02643                                                            ppsubwin->axes.nzgrads,
02644                                                            ppsubwin->logflags[2],
02645                                                            ppsubwin->axes.zgrads,
02646                                                            ppsubwin->axes.nbsubtics[2]); 
02647   }
02648   
02649   return 0;
02650 }
02651 
02652 
02653 
02654 int ComputeNbSubTicsFor3dUse(sciPointObj * pobj, int nbtics, char logflag, double * grads, int nbsubtics_input)
02655 {
02656   int ticsval[] =    {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
02657   int subticsval[] = {6,4,4,3,3,3,2,2,2 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1};
02658   int i;
02659   sciSubWindow * ppsubwin = pSUBWIN_FEATURE (pobj);
02660 
02661 
02662   if(logflag =='l'){
02663     if( (grads[1]-grads[0]) == 1 ) /* intervalle de type ...10^n 10^(n+1)...*/
02664       {
02665         return 9; /* 9 subtics to have a pretty tics/grid in log.*/
02666       }
02667     else
02668       {
02669         return 1; /* no subtics at all (1 but draw on a tics place) */
02670       }
02671   }
02672   else
02673   {
02674     if(ppsubwin->flagNax == FALSE) /* if auto subtics mode == ON */
02675     { 
02676       for(i=0;i<19;i++)
02677       {
02678         if(nbtics == ticsval[i])
02679         {
02680           return subticsval[i];
02681         }
02682       }
02683     }
02684     else /* if auto subtics mode == OFF already computed in Plo2dn.c, Champ.c routines... */
02685     {  /* or given via a.subtics=[nbsubtics_on_x, nbsubtics_on_y, nbsubtics_on_z] command */
02686       return nbsubtics_input;
02687     }
02688   }
02689   
02690   return -1;
02691 }
02692 
02693 
02694 int ChooseFormatForOneGrad(char *c_format, double *grad)
02695 {
02696   int compteur = 0;
02697   double epsilon = 1e-16;
02698   
02699   if((double)(abs((int)*grad)) < epsilon){ /* case where grad is strictly equal to 0. */
02700     *grad = 0.;
02701     strcpy(c_format,"%d");
02702     return 0;
02703   }
02704   
02705   while((int) (*grad) == 0){
02706     compteur++;
02707     *grad = 10*(*grad);
02708     
02709     if(compteur > 100){
02710       Scierror(999,"Error in function ChooseFormatForOneGrad\n");
02711       return -1;
02712     }
02713   }
02714   
02715   sprintf(c_format,"%%.%df",compteur);
02716   
02717   return 0;
02718 }
02719 
02720 
02721 
02722 /*-------------------------------------------------------------------------------------*/
02723 /* compute the 8 vertices (xbox[i],ybox[i],zbox[i]) of an axis aligned box knowing */
02724 /* xmin, xmax, ymin, ymax, zmin and zmax in limits */
02725 void sciGetAxisBox( double limits[6], double xbox[8], double ybox[8], double zbox[8] )
02726 {
02727   xbox[0]=TRX(limits[0],limits[2],limits[4]); /* transfo. 3D of [xmin,ymin,zmin] */
02728   ybox[0]=TRY(limits[0],limits[2],limits[4]); /* into [xbox[0],ybox[0],zbox[0] ] */
02729   zbox[0]=TRZ(limits[0],limits[2],limits[4]); /*                                 */ 
02730   
02731   xbox[1]=TRX(limits[0],limits[3],limits[4]); /* transfo. 3D of [xmin,ymax,zmin] */
02732   ybox[1]=TRY(limits[0],limits[3],limits[4]); /* into [xbox[1],ybox[1],zbox[1] ] */
02733   zbox[1]=TRZ(limits[0],limits[3],limits[4]); /*                                 */
02734   
02735   xbox[2]=TRX(limits[1],limits[3],limits[4]); /* transfo. 3D of [xmax,ymax,zmin] */
02736   ybox[2]=TRY(limits[1],limits[3],limits[4]); /* into [xbox[2],ybox[2],zbox[2] ] */
02737   zbox[2]=TRZ(limits[1],limits[3],limits[4]); /*                                 */
02738   
02739   xbox[3]=TRX(limits[1],limits[2],limits[4]); /* transfo. 3D of [xmax,ymin,zmin] */
02740   ybox[3]=TRY(limits[1],limits[2],limits[4]); /* into [xbox[3],ybox[3],zbox[3] ] */
02741   zbox[3]=TRZ(limits[1],limits[2],limits[4]); /*                                 */
02742   
02743   xbox[4]=TRX(limits[0],limits[2],limits[5]); /* transfo. 3D of [xmin,ymin,zmax] */
02744   ybox[4]=TRY(limits[0],limits[2],limits[5]); /* into [xbox[4],ybox[4],zbox[4] ] */
02745   zbox[4]=TRZ(limits[0],limits[2],limits[5]); /*                                 */
02746   
02747   xbox[5]=TRX(limits[0],limits[3],limits[5]); /* transfo. 3D of [xmin,ymax,zmax] */
02748   ybox[5]=TRY(limits[0],limits[3],limits[5]); /* into [xbox[5],ybox[5],zbox[5] ] */
02749   zbox[5]=TRZ(limits[0],limits[3],limits[5]); /*                                 */
02750   
02751   xbox[6]=TRX(limits[1],limits[3],limits[5]); /* transfo. 3D of [xmax,ymax,zmax] */
02752   ybox[6]=TRY(limits[1],limits[3],limits[5]); /* into [xbox[6],ybox[6],zbox[6] ] */
02753   zbox[6]=TRZ(limits[1],limits[3],limits[5]); /*                                 */
02754   
02755   xbox[7]=TRX(limits[1],limits[2],limits[5]); /* transfo. 3D of [xmax,ymin,zmax] */
02756   ybox[7]=TRY(limits[1],limits[2],limits[5]); /* into [xbox[7],ybox[7],zbox[7] ] */
02757   zbox[7]=TRZ(limits[1],limits[2],limits[5]); /*                                 */
02758 }
02759 /*-------------------------------------------------------------------------------------*/
02760 /* update the Csacle value from new viewing angles */
02761 void sciUpdateScaleAngles( double theta, double alpha )
02762 {
02763   double cost = 0.5 ;
02764   double sint = 0.5 ;
02765   double cosa = 0.5 ;
02766   double sina = 0.5 ;
02767 
02768   cost = cos( DEG2RAD(theta) ) ;
02769   cosa = cos( DEG2RAD(alpha) ) ;
02770   sint = sin( DEG2RAD(theta) ) ;
02771   sina = sin( DEG2RAD(alpha) ) ;
02772   
02773   Cscale.m[0][0]= -sint        ;
02774   Cscale.m[0][1]=  cost        ;
02775   Cscale.m[0][2]=  0           ;
02776   Cscale.m[1][0]= -cost * cosa ;
02777   Cscale.m[1][1]= -sint * cosa ;
02778   Cscale.m[1][2]=  sina        ;
02779   Cscale.m[2][0]=  cost * sina ;
02780   Cscale.m[2][1]=  sint * sina ;
02781   Cscale.m[2][2]=  cosa        ;
02782 
02783 }
02784 
02785 /*-------------------------------------------------------------------------------------*/
02786 /* compute the drawing order of the axes box vertices int xind */
02787 void sciAxesVerticesIndices( integer insideU[4],
02788                              integer insideD[4],
02789                              double  xbox[8]   ,
02790                              double  ybox[8]   ,
02791                              integer xind[8]    )
02792 {
02793   int    i      ;
02794   int    ind    ;
02795   int    ind2   ;
02796   int    ind3   ;
02797   double xmaxi  ;
02798   int    tmpind ;
02799 
02800   /* F.Leray 23.02.04 Mise a 0 du tableau xind pour corriger bug*/
02801   /* dans le cas ind < 3 ET ybox[tmpind] < ybox[tmpind]*/
02802   for( i = 0 ; i < 8 ; i++ )
02803   { 
02804     xind[i] = 0 ;
02805   }
02806 
02807   /* indices */
02808   /* determine the indices for the 3d represention */
02809   xmaxi = ( (double) Maxi(xbox,8L) ) ;
02810   ind = -1 ;
02811   MaxiInd( xbox, 8L, &ind, xmaxi ) ;
02812   if ( ind > 3 )
02813   {
02814     xind[0]=ind;
02815   }
02816   tmpind = ind ;  
02817   MaxiInd(xbox,8L,&ind,xmaxi);
02818   if ( ind > 3 )
02819   {
02820     xind[0] = ind ;
02821   }
02822   if (ybox[tmpind] > ybox[ind] )
02823   {
02824     xind[0] = tmpind ;
02825   }
02826   
02827   if (ind < 0 || ind > 8) 
02828   {
02829     sciprint("xind out of bounds");
02830     xind[0]=0;
02831   }
02832   Nextind(xind[0],&ind2,&ind3);
02833   if (ybox[ind2] > ybox[ind3]) 
02834   {
02835     xind[1]=ind2;insideU[0]=ind3;
02836   }
02837   else 
02838   {
02839     xind[1]=ind3;insideU[0]=ind2;
02840   }
02841   Nextind(ind2,&ind2,&ind3); insideU[1]=xind[0];
02842   insideU[2]=ind2; 
02843   if ( insideU[0] > 3 )
02844   {
02845     insideU[3] = insideU[0] - 4 ;
02846   }
02847   else
02848   {
02849     insideU[3] = insideU[0] + 4 ;
02850   }
02851   xind[2]=ind2;
02852   /* le pointeger en bas qui correspond */        
02853   if ( ind2 > 3 )
02854   {
02855     xind[3] = ind2 - 4 ;
02856   }
02857   else
02858   {
02859     xind[3] = ind2 + 4 ;
02860   }
02861   Nextind(xind[3],&ind2,&ind3);
02862   if (ybox[ind2] < ybox[ind3]) 
02863   {
02864     xind[4]=ind2;insideD[0]=ind3;
02865   }
02866   else  
02867   {
02868     xind[4]=ind3;insideD[0]=ind2;
02869   }
02870   Nextind(ind2,&ind2,&ind3);
02871   insideD[1]=xind[3];
02872   insideD[2]=ind2;
02873   if ( insideD[0] > 3 )
02874   {
02875     insideD[3]=insideD[0] - 4 ;
02876   }
02877   else
02878   {
02879     insideD[3]=insideD[0] + 4 ;
02880   }
02881   xind[5]=ind2;
02882          
02883 }
02884 /*------------------------------------------------------------------------------------------*/
02900 void computeLabelAutoPos( sciPointObj * pLabel, int axisStart[2], int axisEnd[2], int offsets[2] )
02901 {
02902   /* computation are done in double to avoid loss of data */
02903   double centerDir[2]  ; /* give the direction of the line on which is the center. */
02904                          /* it is orthogonal with the axis direction */
02905   double axisMiddle[2] ; /* middle of the axis = ( axisStart + axisEnd ) / 2 */
02906   int    bbox[4][2]    ; /* real bounding box of the label */
02907   double corners[4][2] ; /* the four corners of the boundign box */
02908   double centerDist    ; /* final distance between the center and the axis */
02909   int wantedBlPoint[2] ; /* the position we want for the bottom left point of the axis */
02910   double distance      ;
02911   double rectCenter[2] ;
02912 
02913   if ( axisStart[0] == axisEnd[0] && axisStart[1] == axisEnd[1] )
02914   {
02915     /* the axis is invisible. Its label is not displayed also. */
02916     return ;
02917   }
02918 
02919   /* normalized vector orthogonal to the axe */
02920   /* its direction (+ or -) determines on which side will be displayed the axis */
02921   centerDir[0] = axisStart[1] - axisEnd[1]   ;
02922   centerDir[1] = axisEnd[0]   - axisStart[0] ;
02923   normalize2d( centerDir ) ;
02924 
02925   /* the distance between the aabb and the axis is offsets[0] if the axis is vertical, */
02926   /* offest[1] if horizontal and something in between otherwise */
02927   distance = Abs( (double)offsets[0] * centerDir[0] ) + Abs( (double)offsets[1] * centerDir[1] ) ;
02928 
02929   axisMiddle[0] = ( axisStart[0] + axisEnd[0] ) / 2.0 ;
02930   axisMiddle[1] = ( axisStart[1] + axisEnd[1] ) / 2.0 ;
02931   
02932   /* get the size of the label axis aligned bouding box. */
02933   getTextBoundingBox( pLABEL_FEATURE(pLabel)->text, bbox, NULL ) ;
02934 
02935   /* get the center of the rectangle */
02936   rectCenter[0] = ( bbox[0][0] + bbox[1][0] + bbox[2][0] + bbox[3][0] ) / 4.0 ;
02937   rectCenter[1] = ( bbox[0][1] + bbox[1][1] + bbox[2][1] + bbox[3][1] ) / 4.0 ;
02938 
02939   /* We suppose the box is centered on I and we compute IRi, i=0:3 */
02940   corners[0][0] = bbox[0][0] - rectCenter[0] ;
02941   corners[0][1] = bbox[0][1] - rectCenter[1] ;
02942   corners[1][0] = bbox[1][0] - rectCenter[0] ;
02943   corners[1][1] = bbox[1][1] - rectCenter[1] ;
02944   corners[2][0] = bbox[2][0] - rectCenter[0] ;
02945   corners[2][1] = bbox[2][1] - rectCenter[1] ;
02946   corners[3][0] = bbox[3][0] - rectCenter[0] ;
02947   corners[3][1] = bbox[3][1] - rectCenter[1] ;
02948 
02949   /* compute IRi.v, i=0:3 to get the current distance between Ri and the axis. */
02950   /* Then for each Ri we can compute the need displacment along the centerDir to push it */
02951   /* at distance dist of the axis. Finally, the needed displacement is the maximum of the 4. */
02952   centerDist = distance - DOT_PROD_2D( corners[0], centerDir ) ;
02953   centerDist = Max( centerDist, distance - DOT_PROD_2D( corners[1], centerDir ) ) ;
02954   centerDist = Max( centerDist, distance - DOT_PROD_2D( corners[2], centerDir ) ) ;
02955   centerDist = Max( centerDist, distance - DOT_PROD_2D( corners[3], centerDir ) ) ;
02956 
02957   /* the wanted center is C = I + a.v */
02958   wantedBlPoint[0] = round( axisMiddle[0] + centerDist * centerDir[0] + corners[0][0] ) ;
02959   wantedBlPoint[1] = round( axisMiddle[1] + centerDist * centerDir[1] + corners[0][1] ) ;
02960 
02961   sciSetPosition( pLabel,
02962                   XPixel2Double( wantedBlPoint[0] ),
02963                   YPixel2Double( wantedBlPoint[1] ) ) ;
02964 
02965 }
02966 /*------------------------------------------------------------------------------------------*/
02967 
02968 #undef round

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