Changeset 1928 in Sophya


Ignore:
Timestamp:
Mar 11, 2002, 10:02:23 AM (24 years ago)
Author:
cmv
Message:

Premieere amelioration des label et ticks des axes.
En fait c'est juste pour memoriser le code (qui marche)
mais je vais refondre la logique de l'algotithme.

cmv 11/3/2002

Location:
trunk/SophyaPI/PI
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/SophyaPI/PI/pidrawer.cc

    r1916 r1928  
    307307}
    308308
    309 /* --Methode-Static-- */
    310 void PIDrawer::BestTicks(double rmin,double rmax,int nticks,double& majt)
    311 {
    312 double d = rmax - rmin;
    313 //if (d < 1.e-39) d = 1.e-39;
    314 if (d < 1.e-100) d = 1.e-100;
    315 double ld = log10(d);
    316 double fld = floor(fabs(ld));
    317 double del,del0;
    318 double fac[4] = {2.,5.,10.,20.};
    319 if(ld>=0.) { fld -= 1.; del0 = del = pow(10.,fld); }
    320 else { fld += 2.; del0 = del = pow(10., -fld); }
    321 int k=0;
    322 while( d/del > (double) nticks && k<4 ) { del = fac[k]*del0; k++; }
    323 majt = del;
    324 }
    325 
    326309void
    327310PIDrawer::CalcTicks()
    328311{
    329312  int ntick_x = (aXlog) ? 6 : 10;
    330   BestTicks(xMin,xMax,ntick_x,xMajTickStep);
     313  BestTicks(xMin,xMax,ntick_x,xMajTickStep,xFirstMajTick);
    331314  xMinTickStep = xMajTickStep/5;
    332   xFirstMajTick = int(xMin / xMajTickStep) * xMajTickStep;
    333   if (xFirstMajTick < xMin) xFirstMajTick += xMajTickStep;
    334   xFirstMinTick = int(xMin / xMinTickStep) * xMinTickStep;
     315  xFirstMinTick = floor(xMin / xMinTickStep) * xMinTickStep;
    335316  if (xFirstMinTick < xMin) xFirstMinTick += xMinTickStep;
    336317
    337318  int ntick_y = (aYlog) ? 6 : 12;
    338   BestTicks(yMin,yMax,ntick_y,yMajTickStep);
     319  BestTicks(yMin,yMax,ntick_y,yMajTickStep,yFirstMajTick);
    339320  yMinTickStep = yMajTickStep/5;
    340   yFirstMajTick = int(yMin / yMajTickStep) * yMajTickStep;
    341   if (yFirstMajTick < yMin) yFirstMajTick += yMajTickStep;
    342   yFirstMinTick = int(yMin / yMinTickStep) * yMinTickStep;
     321  yFirstMinTick = floor(yMin / yMinTickStep) * yMinTickStep;
    343322  if (yFirstMinTick < yMin) yFirstMinTick += yMinTickStep;
    344323
     
    524503  // Choix du bon format pour les labels des axes;
    525504  string format;
    526   BonFormatAxes(xBeg,xMax,xStep,format);
     505  BonFormatAxes(xBeg,xMax,xStep,format,1);
    527506
    528507  double xlastlabelfin = xBeg - 2.*(xMax-xBeg);
     
    555534  // Choix du bon format pour les labels des axes;
    556535  string format;
    557   BonFormatAxes(yBeg,yMax,yStep,format);
     536  BonFormatAxes(yBeg,yMax,yStep,format,1);
    558537
    559538  for (double y=yBeg; y<=yMax; y += yStep) {
     
    590569
    591570/* --Methode-Static-- */
    592 int PIDrawer::BonFormatAxes(double xmin,double xmax,double dx,string& format, int add_digit)
     571void PIDrawer::BestTicks(double xmin,double xmax,int nticks,double& steptick,double& xfirsttick)
     572{
     573double d=xmax-xmin; if(d<1.e-100) d=1.e-100; //if (d<1.e-39) d=1.e-39;
     574double ld  = log10(d);
     575double fld = floor( ((ld<0.)? -ld: ld) );
     576double del,del0;
     577if(ld>=0.) {fld-=1.; del0=del=pow(10.,fld);}
     578  else     {fld+=2.; del0=del=pow(10.,-fld);}
     579// xmin  xmax    d       ld       fld -->fld  del0
     580// 1     1500    1499    3.17     3      2    10^2
     581// 1     9500    9499    3.98     3      2    10^2
     582// 1     1.005   0.005   -2.3     2      4    10^-4
     583// 1     1.995   0.995   -0.0022  0      2    10^-2
     584// - Et recherche de la valeur del={del0,2*del0,...,20*del0}
     585// telle que "nticks*del" soit le plus petit nombre ">=d"
     586// Par exemple, si nticks=10:
     587// 1-/ pour le 2sd cas ou d=9499 et del0=100 :
     588// del        =    100    200    500    1000    2000
     589// nticks*del =   1000   2000   5000   10000   20000
     590// d/del      =   94.9   47.4   18.9 | 9.499   4.749  ==> majt = 1000
     591// 2-/ pour le 3ieme cas ou d=5e-3 et del0=1e-4 :
     592// del        =  1e-4   2e-4   5e-4  1e-3   2e-3
     593// nticks*del =  1e-3   2e-3   5e-3  1e-2   2e-2
     594// d/del      =  50     25   | 10    5      2.5       ==> majt = 5e-4
     595int k=0;
     596double fac[4] = {2.,5.,10.,20.};
     597while(d/del>(double)nticks && k<4 ) {del=fac[k]*del0; k++;}
     598steptick=del;
     599xfirsttick = floor(xmin/steptick) * steptick;
     600if(xfirsttick<xmin) xfirsttick += steptick;
     601}
     602
     603/* --Methode-Static-- */
     604int PIDrawer::BonFormatAxes(double xmin,double xmax,double dx,string& format,int add_digit)
    593605// Calcul format optimal pour ecrire les axes
    594 // double = 17 digits : +d.(17digits)e+ddd  -> min 25%17e  -> securite 26%18e
     606// double = 17 digits : +a.bbbbbbbbe+ccc  -> securite 26%18e
    595607// ** add_digit nombre de digit a ajouter au nombre de digit minimum.
     608// But: calculer "ndig" nombre de digits necessaires pour distinguer
     609//      les valeurs xmin+k*dx (<=xmax)
    596610{
    597611 format = "%-6g";  // format par default
    598  if(xmin>=xmax || dx<=0.) return -1;
     612 if(xmin>=xmax) return -1;
     613 if(dx<=0.) dx = 0.9999*(xmax-xmin);
    599614
    600615 //////////// Calcul du nombre de digits necessaires
    601616 char str[32],str0[32];
    602617 int ndig = 0;
    603  //printf("           1         2         3\n");
     618 //printf("           1         2         3 \n");
    604619 //printf("|0123456789012345678901234567890|\n");
    605620 int npass = 0;  // au cas ou dx est tout petit et "x+=dx == x" !
     
    608623   // Il faut gerer le zero car 0 -> 0.000e+00 mais -0 -> -0.000e+00
    609624   if(x>0.)      sprintf(str,"+%-26.18e",x);
    610    else if(x<0.) sprintf(str,"-%-26.18e",fabs(x));
     625   else if(x<0.) sprintf(str,"-%-26.18e",-x);
    611626   else          sprintf(str,"+%-26.18e",0.);
    612627   //printf("|%s|",str);
     
    623638
    624639 //////////// Calcul du bon format
     640 // on differe dans les signes: #1.2345e+123
     641 if(ndig==0) return 0;
     642
     643 // on differe dans les puissances 1.2345e+###
    625644 // position du "e"
    626645 char* cdum = index(str,'e');
    627646 int pose = cdum - str;
    628647 //printf("pose=%d   strlen=%d\n",pose,strlen(str));
    629 
    630  // on differe dans les puissances ..e+ddd
    631648 if(ndig>pose) return 0;
    632649
    633650 // on calcule le nombre de digits necessaires
    634  ndig -= 2;  // +1 - 3 (car par ex:"+9.")
     651 // ... ndig==1 : +9    --> ndig=1
     652 // ... ndig>1  : +9.1  --> ndig-=1
     653 if(ndig>1) ndig -= 1;
    635654
    636655 // on ajoute des digits au cas ou on veut plus que le minimum requis
     
    641660 if(ndig<6) return ndig;
    642661
    643  // Calcule du nombre nn devant le format %nn.ddde
    644  //                        +a.<---ddd--->e+123
    645  //                       nndig = ddd + 8
    646  int nndig = ndig + 8; if(nndig<=0) nndig = 26;
    647 
    648  // On evite d'ecrire d.ddde+00   -> format %f
    649  if(  (xmin>=1. && xmin<10. && xmax>=1. && xmax<10.)
    650    || (xmin>-10. && xmin<=-1. && xmax>-10. && xmax<=-1.) ) {
    651    sprintf(str,"%%-%d.%df",nndig,ndig);
     662 double axmin=fabs(xmin), axmax=fabs(xmax);
     663 if(axmax<axmin) {dx=axmin; axmin=axmax; axmax=dx;}
     664 if(axmin>=0.01 && axmax<1000.) {
     665   // On evite d'ecrire +a.bbbe+ccc pour ccc=-1,0,1,2 -> format %f
     666   // Ex: 1.2345e+2 -> 123.45   /  -1.2345e+2 -> -123.45
     667   //     1.2345e-1 -> 0.12345  /  -1.2345e-1 -> -0.12345
     668   // Calcul du format %-nn.mmf
     669   int mm=-1, nn;
     670   if(axmax<0.1)        {mm=ndig+1; nn=mm+3;} // +0.012345
     671   else if(axmax<1.)    {mm=ndig;   nn=mm+3;} // +0.12345
     672   else if(axmax<10.)   {mm=ndig-1; nn=mm+3;} // +1.2345
     673   else if(axmax<100.)  {mm=ndig-2; nn=mm+4;} // +12.345
     674   else if(axmax<1000.) {mm=ndig-3; nn=mm+5;} // +123.45
     675   if(mm<0.) {mm=ndig; nn=mm+3;}              // +0.12345 (defaut)
     676   sprintf(str,"%%-%d.%df",nn,mm);
    652677 } else {
    653    sprintf(str,"%%-%d.%de",nndig,ndig);
     678   // Calcul du nombre "nn" devant le format %-nn.mme
     679   //   +d.<--ddd-->e+123
     680   //   1 2         34567
     681   //   nn = ndig+7   mm = ndig-1
     682   sprintf(str,"%%-%d.%de",ndig+7,ndig-1);
    654683 }
     684
    655685 format = str;
    656686 //printf("format= %s\n",format.c_str());
  • trunk/SophyaPI/PI/pidrawer.h

    r1906 r1928  
    100100//  --- Methode- static ----
    101101//  Calcul des Distances optimales des subdivisions
    102   static void        BestTicks(double rmin,double rmax,int nticks,double& majt);
     102  static void BestTicks(double xmin,double xmax,int nticks,double& steptick,double& xfirsttick);
    103103//  Calcul du format optimal pour les axes
    104104  static int BonFormatAxes(double xmin,double xmax,double dx,string& format, int add_digit=0);
  • trunk/SophyaPI/PI/piscdrawwdg.cc

    r1922 r1928  
    608608{
    609609  string format = "%-g";
    610   //PIDrawer::BonFormatAxes(xmin,xmax,(xmax-xmin)*0.9999,format,2);
    611610  double xm = (fabs(xmax)>fabs(xmin)) ? fabs(xmax): fabs(xmin);
    612611  double dx = fabs(xmax-xmin)/500.;
    613   PIDrawer::BonFormatAxes(xm,xm+dx,dx*0.9999,format,0);
     612  PIDrawer::BonFormatAxes(xm,xm+dx,dx*0.9999,format,1);
    614613  return format;
    615614}
    616 
    617 
Note: See TracChangeset for help on using the changeset viewer.