Changeset 2080 in Sophya for trunk/SophyaPI/PI/pidrawer.cc


Ignore:
Timestamp:
Jul 2, 2002, 2:28:08 PM (23 years ago)
Author:
ansari
Message:

Ajout classe PIAxes/Fonctions de trace d'axes - Reza 02/07/2002

File:
1 edited

Legend:

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

    r2057 r2080  
    1212#include "ucckprot.h"
    1313
    14 #define dble_SWAP(__a,__b) {double __tmp=__a; __a=__b; __b=__tmp;}
    1514
    1615//++
     
    360359
    361360void
    362 PIDrawer::CalcTicks()
    363 {
    364   int ntick_x = (aXlog) ? 6 : 10;
    365   BestTicks(xMin,xMax,ntick_x,xMajTickStep,xFirstMajTick);
    366   xMinTickStep = xMajTickStep/5;
    367   xFirstMinTick = floor(xMin / xMinTickStep) * xMinTickStep;
    368   if(xFirstMinTick < xMin) xFirstMinTick += xMinTickStep;
    369 
    370   int ntick_y = (aYlog) ? 6 : 12;
    371   BestTicks(yMin,yMax,ntick_y,yMajTickStep,yFirstMajTick);
    372   yMinTickStep = yMajTickStep/5;
    373   yFirstMinTick = floor(yMin / yMinTickStep) * yMinTickStep;
    374   if(yFirstMinTick < yMin) yFirstMinTick += yMinTickStep;
    375 
    376   yMajTickLen = (xMax-xMin)/100;
    377   yMinTickLen = (xMax-xMin)/250;
    378   xMajTickLen = (yMax-yMin)/100;
    379   xMinTickLen = (yMax-yMin)/250;
    380 }
    381 
    382 void
    383361PIDrawer::SetAxesFlags(unsigned int flags)
    384362{
     
    397375{
    398376  g->NoClip();
    399   if (GetGraphicAtt().GetLineAtt() == PI_NotDefLineAtt)  g->SelLine(PI_ThinLine);
    400   else g->SelLine(GetGraphicAtt().GetLineAtt());
    401   if (GetGraphicAtt().GetColor() == PI_NotDefColor) g->SelForeground(PI_Black);
    402   else g->SelForeground(GetGraphicAtt().GetColor());
    403   //  On calcule les ticks
    404   CalcTicks();
    405 
    406   unsigned int flags = axesFlags;
    407 
    408   if (flags & kStdAxes) {
    409 
    410     // Les axes
    411    
    412     g->DrawLine(xMin, (yMin+yMax)/2., xMax, (yMin+yMax)/2.);
    413     g->DrawLine((xMin+xMax)/2., yMin, (xMin+xMax)/2., yMax);
    414 
    415     // La grille en pointilles
    416 
    417     if (flags & kGridOn) DrawGrid(g);
     377  PIAxes axes;
     378  axes.DrawXYAxes(g, mGrAtt, axesFlags, axesAFSz, XMin(), XMax(), YMin(), YMax());
     379  g->Clip();
     380}
     381
    418382 
    419     // Les ticks majeurs
    420  
    421     if (flags & kMajTicks) {
    422         DrawHTicks(g, (yMin+yMax)/2., xMajTickLen, xMajTickLen, xFirstMajTick, xMajTickStep);
    423         DrawVTicks(g, (xMin+xMax)/2., yMajTickLen, yMajTickLen, yFirstMajTick, yMajTickStep);
    424     }
    425    
    426     // Les ticks mineurs
    427  
    428     if (flags & kMinTicks) {
    429         DrawHTicks(g, (yMin+yMax)/2., xMinTickLen, xMinTickLen, xFirstMinTick, xMinTickStep);
    430         DrawVTicks(g, (xMin+xMax)/2., yMinTickLen, yMinTickLen, yFirstMinTick, yMinTickStep);
    431     }
    432    
    433     // Les labels
    434    
    435     if (flags & kLabels) {
    436       if (!aYdir)
    437         DrawHLabels(g, (yMin+yMax)/2.-xMajTickLen*2, xFirstMajTick, xMajTickStep,PI_VerticalTop);
    438       else
    439         DrawHLabels(g, (yMin+yMax)/2.+xMajTickLen*2, xFirstMajTick, xMajTickStep,PI_VerticalTop);
    440       if (!aXdir)
    441         DrawVLabels(g, (xMin+xMax)/2.-yMajTickLen*2, yFirstMajTick, yMajTickStep,PI_HorizontalRight);
    442       else
    443         DrawVLabels(g, (xMin+xMax)/2.+yMajTickLen*2, yFirstMajTick, yMajTickStep,PI_HorizontalRight);
    444     }
    445    
    446   }
    447  
    448   if (flags & kBoxAxes) {
    449  
    450     // La boite
    451    
    452     g->DrawLine(xMin, yMin, xMax, yMin);
    453     g->DrawLine(xMax, yMin, xMax, yMax);
    454     g->DrawLine(xMax, yMax, xMin, yMax);
    455     g->DrawLine(xMin, yMax, xMin, yMin);
    456 
    457     // Longueur des ticks
    458    
    459     double extXMajTickLen = flags&kExtTicks ? xMajTickLen : 0;
    460     double intXMajTickLen = flags&kIntTicks ? xMajTickLen : 0;
    461     double extXMinTickLen = flags&kExtTicks ? xMinTickLen : 0;
    462     double intXMinTickLen = flags&kIntTicks ? xMinTickLen : 0;
    463     double extYMajTickLen = flags&kExtTicks ? yMajTickLen : 0;
    464     double intYMajTickLen = flags&kIntTicks ? yMajTickLen : 0;
    465     double extYMinTickLen = flags&kExtTicks ? yMinTickLen : 0;
    466     double intYMinTickLen = flags&kIntTicks ? yMinTickLen : 0;
    467 
    468     // La grille en pointilles
    469 
    470     if (flags & kGridOn) DrawGrid(g);
    471 
    472     // Les ticks majeurs
    473  
    474     if (flags & kMajTicks) {
    475         DrawHTicks(g, yMin, intXMajTickLen, extXMajTickLen, xFirstMajTick, xMajTickStep);
    476         DrawHTicks(g, yMax, extXMajTickLen, intXMajTickLen, xFirstMajTick, xMajTickStep);
    477         DrawVTicks(g, xMin, extYMajTickLen, intYMajTickLen, yFirstMajTick, yMajTickStep);
    478         DrawVTicks(g, xMax, intYMajTickLen, extYMajTickLen, yFirstMajTick, yMajTickStep);
    479     }
    480    
    481     // Les ticks mineurs
    482  
    483     if (flags & kMinTicks) {
    484         DrawHTicks(g, yMin, intXMinTickLen, extXMinTickLen, xFirstMinTick, xMinTickStep);
    485         DrawHTicks(g, yMax, extXMinTickLen, intXMinTickLen, xFirstMinTick, xMinTickStep);
    486         DrawVTicks(g, xMin, extYMinTickLen, intYMinTickLen, yFirstMinTick, yMinTickStep);
    487         DrawVTicks(g, xMax, intYMinTickLen, extYMinTickLen, yFirstMinTick, yMinTickStep);
    488     }
    489 
    490 
    491     // Les labels
    492    
    493     if (flags & kLabels) {
    494       if (!aYdir) {
    495         DrawHLabels(g, g->DeltaUCY(yMin, -xMajTickLen*2), xFirstMajTick, xMajTickStep,PI_VerticalTop);
    496         //DrawHLabels(g, g->DeltaUCY(yMax,  xMajTickLen*2), xFirstMajTick, xMajTickStep,PI_VerticalBottom);
    497       }
    498       else {
    499         //DrawHLabels(g, g->DeltaUCY(yMin, -xMajTickLen*2), xFirstMajTick, xMajTickStep,PI_VerticalBottom);
    500         DrawHLabels(g, g->DeltaUCY(yMax,  xMajTickLen*2), xFirstMajTick, xMajTickStep,PI_VerticalTop);
    501       }
    502       if (!aXdir) {
    503         DrawVLabels(g, g->DeltaUCX(xMin, -yMajTickLen*2), yFirstMajTick, yMajTickStep,PI_HorizontalRight);
    504         //DrawVLabels(g, g->DeltaUCX(xMax,  yMajTickLen*2), yFirstMajTick, yMajTickStep,PI_HorizontalLeft);
    505       }
    506       else {
    507         //DrawVLabels(g, g->DeltaUCX(xMin, -yMajTickLen*2), yFirstMajTick, yMajTickStep,PI_HorizontalLeft);
    508         DrawVLabels(g, g->DeltaUCX(xMax,  yMajTickLen*2), yFirstMajTick, yMajTickStep,PI_HorizontalRight);
    509       }
    510     }
    511   }
    512   g->Clip();
    513 }
    514 
    515  
    516383
    517384void
     
    529396{
    530397}
    531 
    532 void
    533 PIDrawer::DrawHTicks(PIGraphicUC* g, double y, double tickUp, double tickDown, double xBeg, double xStep)
    534 {
    535   for (double x=xBeg; x<=xMax+xStep/10.; x += xStep)
    536     g->DrawLine(x, g->DeltaUCY(y, -tickDown), x, g->DeltaUCY(y, tickUp));
    537 }
    538 
    539 void
    540 PIDrawer::DrawVTicks(PIGraphicUC* g, double x, double tickLeft, double tickRight, double yBeg, double yStep)
    541 {
    542   for (double y=yBeg; y<=yMax; y += yStep)
    543     g->DrawLine(g->DeltaUCX(x, -tickLeft), y, g->DeltaUCX(x,tickRight), y);
    544 }
    545 
    546 void
    547 PIDrawer::DrawHLabels(PIGraphicUC* g, double y, double xBeg, double xStep, unsigned long just)
    548 {
    549   double fsz = xMajTickLen*3.5;
    550   if(axesAFSz) g->SelFontSz(fsz);
    551 
    552   // Choix du bon format pour les labels des axes;
    553   char label[64]; string format; double fac=1.; bool p10=false;
    554   int npuiss = BonFormatAxes(xBeg,xMax,xStep,format,2,1);
    555   if(npuiss<-2 || npuiss>3) {p10 = true; fac=pow(10.,(double)npuiss);}
    556   else BonFormatAxes(xBeg,xMax,xStep,format,0,1);
    557 
    558   double xOffset = 0;
    559   double xlastlabelfin = xBeg - 2.*(xMax-xBeg);
    560   for(double x=xBeg; x<=xMax+xStep/10.; x+=xStep) {
    561     //Attention erreur d'arrondi x->0 (on code 5.1698e-26 au lieu de 0)
    562     double xx = (fabs(x/xStep)<1.e-5) ? 0.: x;
    563     sprintf(label,format.c_str(),xx/fac);
    564     for(int kk=0;kk<64;kk++) if(label[kk]==' ') {label[kk]='\0'; break;}
    565     double largeur = g->CalcStringWidth(label);
    566     if(aXdir) xOffset = largeur/2; else xOffset=-largeur/2;
    567     if(x+xOffset > xlastlabelfin) {
    568       g->DrawString(x,y,label,PI_HorizontalCenter|just);
    569       xlastlabelfin = x + xOffset + 1.1*largeur;
    570     }
    571   }
    572 
    573   if(p10) {
    574     PIGrCoord asc,desc;
    575     double h = g->GetFontHeight(asc,desc);
    576     if((aYdir && (just&PI_VerticalBottom)) || (!aYdir && (just&PI_VerticalTop)) ) h = -h;
    577     double xm = (aXdir)? xMin: xMax;
    578     double ym = g->DeltaUCY(y,1.5*h);
    579     sprintf(label,"%d",npuiss);
    580     g->DrawCompString(xm,ym,"x 10",label,NULL,PI_HorizontalCenter|just);
    581   }
    582 
    583 }
    584 
    585 void
    586 PIDrawer::DrawVLabels(PIGraphicUC* g, double x, double yBeg, double yStep, unsigned long just)
    587 {
    588   double fsz = xMajTickLen*3.5;
    589   if(axesAFSz) g->SelFontSz(fsz);
    590 
    591   // Choix du bon format pour les labels des axes;
    592   char label[64]; string format; double fac=1.; bool p10=false;
    593   int npuiss = BonFormatAxes(yBeg,yMax,yStep,format,2,1);
    594   if(npuiss<-2 || npuiss>3) {p10 = true; fac=pow(10.,(double)npuiss);}
    595   else BonFormatAxes(yBeg,yMax,yStep,format,0,1);
    596 
    597   for(double y=yBeg; y<=yMax; y += yStep) {
    598     double yy = (fabs(y/yStep)<1.e-5) ? 0.: y;
    599     sprintf(label,format.c_str(),yy/fac);
    600     for(int kk=0;kk<64;kk++) if(label[kk]==' ') {label[kk]='\0'; break;}
    601     g->DrawString(x,y,label,PI_VerticalCenter|just);
    602   }
    603 
    604   if(p10) {
    605     PIGrCoord asc,desc;
    606     double h = g->GetFontHeight(asc,desc);
    607     if(aYdir) h = -h;
    608     double ym = (aYdir)? yMin: yMax; ym = g->DeltaUCY(ym,h);
    609     sprintf(label,"%d",npuiss);
    610     g->DrawCompString(x,ym,"x 10",label,NULL,PI_VerticalBottom|just);
    611   }
    612 
    613 }
    614 
    615 void
    616 PIDrawer::DrawGrid(PIGraphicUC* g)
    617 {
    618   PILineAtt savlineatt = g->GetLineAtt();
    619 //  g->SelLine(PI_ThinDashedLine);
    620   g->SelLine(PI_ThinDottedLine);
    621 
    622   for (double x=xFirstMajTick; x<=xMax; x += xMajTickStep)
    623     g->DrawLine(x, yMin, x, yMax);
    624 
    625   for (double y=yFirstMajTick; y<=yMax; y += yMajTickStep)
    626     g->DrawLine(xMin, y, xMax, y);
    627 
    628   g->SelLine(savlineatt);
    629 }
    630 
    631 ///////////////////////////////////////////////////////////////////////////
    632 /* --Methode-Static-- */
    633 void PIDrawer::BestTicks(double xmin,double xmax,int nticks
    634                         ,double& steptick,double& xfirsttick)
    635 // *** Calcul de l'intervalle entre les ticks et de la valeur du premier tick
    636 {
    637 double d=xmax-xmin; if(d<1.e-100) d=1.e-100; //if (d<1.e-39) d=1.e-39;
    638 double ld  = log10(d);
    639 double fld = floor( ((ld<0.)? -ld: ld) );
    640 double del,del0;
    641 if(ld>=0.) {fld-=1.; del0=del=pow(10.,fld);}
    642   else     {fld+=2.; del0=del=pow(10.,-fld);}
    643 // *** Intervalle entre les ticks
    644 // xmin  xmax    d       ld       fld -->fld  del0
    645 // 1     1500    1499    3.17     3      2    10^2
    646 // 1     9500    9499    3.98     3      2    10^2
    647 // 1     1.005   0.005   -2.3     2      4    10^-4
    648 // 1     1.995   0.995   -0.0022  0      2    10^-2
    649 // - Et recherche de la valeur del={del0,2*del0,...,20*del0}
    650 // telle que "nticks*del" soit le plus petit nombre ">=d"
    651 // Par exemple, si nticks=10:
    652 // 1-/ pour le 2sd cas ou d=9499 et del0=100 :
    653 // del        =    100    200    500    1000    2000
    654 // nticks*del =   1000   2000   5000   10000   20000
    655 // d/del      =   94.9   47.4   18.9 | 9.499   4.749  ==> majt = 1000
    656 // 2-/ pour le 3ieme cas ou d=5e-3 et del0=1e-4 :
    657 // del        =  1e-4   2e-4   5e-4  1e-3   2e-3
    658 // nticks*del =  1e-3   2e-3   5e-3  1e-2   2e-2
    659 // d/del      =  50     25   | 10    5      2.5       ==> majt = 5e-4
    660 int k=0;
    661 double fac[4] = {2.,5.,10.,20.};
    662 while(d/del>(double)nticks && k<4 ) {del=fac[k]*del0; k++;}
    663 steptick=del;
    664 //***  Valeur du premier tick
    665 xfirsttick = floor(xmin/steptick); if(xmin<0.) xfirsttick+=1.;
    666 xfirsttick *= steptick;
    667 if(xfirsttick<xmin) xfirsttick += steptick;
    668 }
    669 
    670 /* --Methode-Static-- */
    671 int PIDrawer::BonFormatAxes(double xmin,double xmax,double xstep
    672                            ,string& format,int typf,int add_digit)
    673 // *** Calcul format optimal pour ecrire les labels numeriques des axes:
    674 // ---- Input
    675 // . xmin,xmax : limites du plot sur l'axe considere.
    676 // . xstep : distance entre les ticks.
    677 // . add_digit : nombre de digits a ajouter au nombre de digits minimum.
    678 // . typf : type de format en sortie
    679 //        0 : format optimum %-nn.mme ou %-nn.mmf selon valeurs
    680 //        1 : format %-nn.mme
    681 //        2 : format %-nn.mmf pour imprimer x/10^npuiss
    682 //            tel que x/10^npuiss soit entre 0 et 10
    683 // ---- Output
    684 // . format : le format d'impression
    685 // ---- Return:
    686 // Si typ=0 ou 1
    687 //   "ndig" : nombre de digits necessaires pour distinguer
    688 //            les valeurs xmin+k*dx (<=xmax)
    689 // Si typ=2
    690 //   "npuiss" : tel que x/10^npuiss soit entre 0 et 10
    691 //              Dans ce cas le format est celui qui imprime x/10^npuiss
    692 {
    693  format = "%-5g";  // format par default
    694  if(xmin>=xmax) {if(typf==2) return 0; else return -1;}
    695 
    696  if(xstep<=0. || xstep>xmax-xmin) xstep = xmax-xmin;
    697 
    698  double axmin=fabs(xmin), axmax=fabs(xmax);
    699  if(axmin>axmax) dble_SWAP(axmin,axmax)
    700 
    701  double l10amax = log10(axmax), l10xstep = log10(xstep);
    702  int il10amax = int(floor(l10amax));
    703 
    704  // choix du type de format
    705  char ftype = 'e';
    706  int npuiss = 0;
    707  if(typf==2) {
    708    npuiss = il10amax;
    709    if(npuiss<-300 || npuiss>300) {
    710      ftype='e'; npuiss=0;
    711    } else {
    712      // On recalcule les valeurs de decision pour  axmax/10^npuiss, xstep/10^npuiss
    713      l10amax -= (double)npuiss; l10xstep -=  (double)npuiss;
    714      il10amax = int(floor(l10amax));
    715      ftype = 'f';
    716    }
    717  } else if(typf==1) {
    718    ftype='e';
    719  } else {
    720    ftype='e';
    721    // On evite d'ecrire +a.bbbe+ccc -> format %f
    722    // Ex: 1.2345e+2 -> 123.45   /  -1.2345e+2 -> -123.45
    723    //     1.2345e-1 -> 0.12345  /  -1.2345e-1 -> -0.12345
    724    if((axmin>=1e-4 || axmin==0.) && axmax<1e4) ftype='f';
    725  }
    726 
    727  //printf("BonFormatAxes[npuiss=%d]: xmin=%-21.14e xmax=%-21.14e\n",npuiss,xmin,xmax);
    728  //printf("        xstep=%-21.14e log10(xstep/10^%d)=%g\n",xstep,npuiss,l10xstep);
    729  //printf("        axmax=%-21.14e log10(axmax/10^%d)=%g diff=%g\n"
    730  //      ,axmax,npuiss,l10amax,l10amax-l10xstep);
    731 
    732  // Nombre de digits necessaires pour ecrire axmax et xstep
    733  int ndig = il10amax  -  int(floor(l10xstep));
    734  if(ndig<0) ndig *= -1;  ndig += 1;
    735  //printf("ndig=%d",ndig);
    736  
    737  // Add more digits (or suppress digits)
    738  ndig += add_digit; if(ndig<0) ndig=0;
    739  //printf(" + %d  ==> ndig=%d\n",add_digit,ndig);
    740 
    741  // Calcul du bon format
    742  char str[16];
    743  if(ftype=='f') { // Calcul du format %-nn.mmf
    744    int mm=-1, nn;
    745    if(il10amax<0) { // +0.12345 +0.0012345 +0.0012345 ...
    746      mm = ndig - il10amax - 1; nn = mm+3;
    747    } else {         // +1.2345 +12.345 +123.45 ...
    748      mm = ndig - il10amax - 1; nn = ndig+2;
    749    }
    750    //printf("format %%f : mm=%d  nn=%d\n",mm,nn);
    751    if(mm<0.) mm=0; if(nn<mm+3) nn=mm+3;
    752    sprintf(str,"%%-%d.%df",nn,mm);
    753  } else if(ftype=='e') { // Calcul du format %-nn.mme
    754    //   +d.<--ddd-->e+123
    755    //   1 2         34567  ==> nn=ndig+7   mm=ndig-1
    756    sprintf(str,"%%-%d.%de",ndig+7,ndig-1);
    757  }
    758 
    759  format = str;
    760  //printf("format=[%s]\n",format.c_str());
    761 
    762  if(typf==2) return npuiss;
    763  return ndig;
    764 }
Note: See TracChangeset for help on using the changeset viewer.