Changeset 1930 in Sophya


Ignore:
Timestamp:
Mar 11, 2002, 11:10:09 PM (24 years ago)
Author:
cmv
Message:

BonFormat plus performant cmv 11/3/02

Location:
trunk/SophyaPI/PI
Files:
3 edited

Legend:

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

    r1928 r1930  
    88#include <iostream.h>
    99// #include <typeinfo>
     10#include "utilgeom.h"
    1011#include "pidrawer.h"
    11 
    1212#include "pidrwtools.h"
    1313
     
    314314  xMinTickStep = xMajTickStep/5;
    315315  xFirstMinTick = floor(xMin / xMinTickStep) * xMinTickStep;
    316   if (xFirstMinTick < xMin) xFirstMinTick += xMinTickStep;
     316  if(xFirstMinTick < xMin) xFirstMinTick += xMinTickStep;
    317317
    318318  int ntick_y = (aYlog) ? 6 : 12;
     
    320320  yMinTickStep = yMajTickStep/5;
    321321  yFirstMinTick = floor(yMin / yMinTickStep) * yMinTickStep;
    322   if (yFirstMinTick < yMin) yFirstMinTick += yMinTickStep;
     322  if(yFirstMinTick < yMin) yFirstMinTick += yMinTickStep;
    323323
    324324  yMajTickLen = (xMax-xMin)/100;
     
    569569
    570570/* --Methode-Static-- */
    571 void PIDrawer::BestTicks(double xmin,double xmax,int nticks,double& steptick,double& xfirsttick)
     571void PIDrawer::BestTicks(double xmin,double xmax,int nticks
     572                        ,double& steptick,double& xfirsttick)
     573// *** Calcul de l'intervalle entre les ticks et de la valeur du premier tick
    572574{
    573575double d=xmax-xmin; if(d<1.e-100) d=1.e-100; //if (d<1.e-39) d=1.e-39;
     
    577579if(ld>=0.) {fld-=1.; del0=del=pow(10.,fld);}
    578580  else     {fld+=2.; del0=del=pow(10.,-fld);}
     581// *** Intervalle entre les ticks
    579582// xmin  xmax    d       ld       fld -->fld  del0
    580583// 1     1500    1499    3.17     3      2    10^2
     
    597600while(d/del>(double)nticks && k<4 ) {del=fac[k]*del0; k++;}
    598601steptick=del;
    599 xfirsttick = floor(xmin/steptick) * steptick;
     602//***  Valeur du premier tick
     603xfirsttick = floor(xmin/steptick); if(xmin<0.) xfirsttick+=1.;
     604xfirsttick *= steptick;
    600605if(xfirsttick<xmin) xfirsttick += steptick;
    601606}
    602607
    603608/* --Methode-Static-- */
    604 int PIDrawer::BonFormatAxes(double xmin,double xmax,double dx,string& format,int add_digit)
    605 // Calcul format optimal pour ecrire les axes
    606 // double = 17 digits : +a.bbbbbbbbe+ccc  -> securite 26%18e
    607 // ** 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)
    610 {
    611  format = "%-6g";  // format par default
     609int PIDrawer::BonFormatAxes(double xmin,double xmax,double xstep
     610                           ,string& format,int add_digit)
     611// *** Calcul format optimal pour ecrire les labels numeriques des axes:
     612// - Les axes vont de "xmin" a "xmax".
     613// - On veut un intervalle "xstep" entre les ticks.
     614// - Le programme retourne le format dans le "string format"
     615// - add_digit: nombre de digit a ajouter au nombre de digit minimum.
     616// Return: "ndig" nombre de digits necessaires pour distinguer
     617//         les valeurs xmin+k*dx (<=xmax)
     618{
     619 format = "%-5g";  // format par default
    612620 if(xmin>=xmax) return -1;
    613  if(dx<=0.) dx = 0.9999*(xmax-xmin);
    614 
    615  //////////// Calcul du nombre de digits necessaires
    616  char str[32],str0[32];
    617  int ndig = 0;
    618  //printf("           1         2         3 \n");
    619  //printf("|0123456789012345678901234567890|\n");
    620  int npass = 0;  // au cas ou dx est tout petit et "x+=dx == x" !
    621  for(double x=xmin; x<=xmax; x+=dx) {
    622    // Le format %e ecrit les "-" pour x<0 mais pas les "+" pour x>0
    623    // Il faut gerer le zero car 0 -> 0.000e+00 mais -0 -> -0.000e+00
    624    if(x>0.)      sprintf(str,"+%-26.18e",x);
    625    else if(x<0.) sprintf(str,"-%-26.18e",-x);
    626    else          sprintf(str,"+%-26.18e",0.);
    627    //printf("|%s|",str);
    628    if(npass!=0) {
    629      int j;
    630      for(j=0;j<(int)strlen(str);j++) if(str0[j]!=str[j]) break;
    631      //printf(" -> ...j= %d",j);
    632      if(j>ndig) ndig=j;
    633      //printf("    ndig= %d  |%26.18e| (%-6g)\n",ndig,x,x);
    634    } //else printf("\n");
    635    strcpy(str0,str);
    636    if(npass>1000) break; npass++;
    637  }
    638 
    639  //////////// 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+###
    644  // position du "e"
    645  char* cdum = index(str,'e');
    646  int pose = cdum - str;
    647  //printf("pose=%d   strlen=%d\n",pose,strlen(str));
    648  if(ndig>pose) return 0;
    649 
    650  // on calcule le nombre de digits necessaires
    651  // ... ndig==1 : +9    --> ndig=1
    652  // ... ndig>1  : +9.1  --> ndig-=1
    653  if(ndig>1) ndig -= 1;
    654 
    655  // on ajoute des digits au cas ou on veut plus que le minimum requis
    656  ndig += add_digit;
    657 
    658  // Si peu de digits on reste avec le format par defaut
    659  // Attention: %6g arrondi le 6ieme digit -> ndig<5 !
    660  if(ndig<6) return ndig;
     621
     622 if(xstep<=0. || xstep>xmax-xmin) xstep = xmax-xmin;
    661623
    662624 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
     625 if(axmin>axmax) swap(axmin,axmax);
     626 double l10amax = log10(axmax), l10xstep = log10(xstep);
     627
     628 //printf("BonFormatAxes: xmin=%-21.14e xmax=%-21.14e\n",xmin,xmax);
     629 //printf("        xstep=%-21.14e log10(xstep)=%g\n",xstep,l10xstep);
     630 //printf("        axmax=%-21.14e log10(axmax)=%g diff=%g\n"
     631 //      ,axmax,l10amax,l10amax-l10xstep);
     632
     633 // Nombre de digits necessaires pour ecrire amax et xstep
     634 int il10amax = int(floor(l10amax));
     635 int ndig = il10amax  -  int(floor(l10xstep));
     636 if(ndig<0) ndig *= -1;
     637 ndig += 1;
     638 //printf("ndig=%d",ndig);
     639 
     640 // Add more digits (or suppress digits)
     641 ndig += add_digit; if(ndig<0) ndig=0;
     642 //printf(" + %d  ==> ndig=%d\n",add_digit,ndig);
     643
     644 // Calcul du bon format
     645 char str[16];
     646 if(axmin>=1e-4 && axmax<1e4) {
     647   // On evite d'ecrire +a.bbbe+ccc -> format %f
    666648   // Ex: 1.2345e+2 -> 123.45   /  -1.2345e+2 -> -123.45
    667649   //     1.2345e-1 -> 0.12345  /  -1.2345e-1 -> -0.12345
    668650   // Calcul du format %-nn.mmf
    669651   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)
     652   if(il10amax<0) { // +0.12345 +0.0012345 +0.0012345 ...
     653     mm = ndig - il10amax - 1; nn = mm+3;
     654   } else {         // +1.2345 +12.345 +123.45 ...
     655     mm = ndig - il10amax - 1; nn = ndig+2;
     656   }
     657   //printf("format %%f : mm=%d  nn=%d\n",mm,nn);
     658   if(mm<0.) mm=0; if(nn<mm+3) nn=mm+3;
    676659   sprintf(str,"%%-%d.%df",nn,mm);
    677660 } else {
     
    684667
    685668 format = str;
    686  //printf("format= %s\n",format.c_str());
     669 //printf("format=[%s]\n",format.c_str());
     670
    687671 return ndig;
    688672}
  • trunk/SophyaPI/PI/pidrawer.h

    r1928 r1930  
    100100//  --- Methode- static ----
    101101//  Calcul des Distances optimales des subdivisions
    102   static void BestTicks(double xmin,double xmax,int nticks,double& steptick,double& xfirsttick);
     102  static void BestTicks(double xmin,double xmax,int nticks
     103                       ,double& steptick,double& xfirsttick);
    103104//  Calcul du format optimal pour les axes
    104   static int BonFormatAxes(double xmin,double xmax,double dx,string& format, int add_digit=0);
     105  static int BonFormatAxes(double xmin,double xmax,double xstep
     106                          ,string& format,int add_digit=0);
    105107
    106108//  Les objets/methodes suivants devraient etre protected     
  • trunk/SophyaPI/PI/piscdrawwdg.cc

    r1928 r1930  
    610610  double xm = (fabs(xmax)>fabs(xmin)) ? fabs(xmax): fabs(xmin);
    611611  double dx = fabs(xmax-xmin)/500.;
    612   PIDrawer::BonFormatAxes(xm,xm+dx,dx*0.9999,format,1);
     612  PIDrawer::BonFormatAxes(xm,xm+dx,dx,format,1);
    613613  return format;
    614614}
Note: See TracChangeset for help on using the changeset viewer.