Changeset 2091 in Sophya for trunk/SophyaPI
- Timestamp:
- Jul 13, 2002, 6:08:49 PM (23 years ago)
- Location:
- trunk/SophyaPI/PI
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/SophyaPI/PI/piaxes.cc
r2088 r2091 9 9 #include "piaxes.h" 10 10 11 inline void dble_SWAP(double a, doubleb) {double tmp=a; a=b; b=tmp;}11 inline void dble_SWAP(double& a,double& b) {double tmp=a; a=b; b=tmp;} 12 12 13 13 /* --Methode-- */ … … 166 166 aYlog = g->isLogScaleY(); 167 167 168 int ntick_x = (aXlog) ? 6 : 10; 169 BestTicks(xMin,xMax,ntick_x,xMajTicks,xMinTicks); 170 171 int ntick_y = (aYlog) ? 6 : 12; 172 BestTicks(yMin,yMax,ntick_y,yMajTicks,yMinTicks); 168 int ntick_x = (aXlog) ? 10 : 10; 169 if(aXlog) BestTicksLog(xMin,xMax,ntick_x,xMajTicks,xMinTicks); 170 else BestTicks(xMin,xMax,ntick_x,xMajTicks,xMinTicks); 171 172 int ntick_y = (aYlog) ? 12 : 12; 173 if(aYlog) BestTicksLog(yMin,yMax,ntick_y,yMajTicks,yMinTicks); 174 else BestTicks(yMin,yMax,ntick_y,yMajTicks,yMinTicks); 173 175 174 176 yMajTickLen = (xMax-xMin)/100; … … 183 185 double tickDown, vector<double>& xticks) 184 186 { 185 if(xticks.size() <=0) return;187 if(xticks.size()==0) return; 186 188 for(unsigned int i=0;i<xticks.size();i++) { 189 if(xticks[i]<xMin) continue; 187 190 if(xticks[i]>xMax) break; 188 191 g->DrawLine(xticks[i],g->DeltaUCY(y,-tickDown),xticks[i],g->DeltaUCY(y,tickUp)); … … 194 197 double tickRight, vector<double>& yticks) 195 198 { 196 if(yticks.size() <=0) return;199 if(yticks.size()==0) return; 197 200 for(unsigned int i=0;i<yticks.size();i++) { 201 if(yticks[i]<yMin) continue; 198 202 if(yticks[i]>yMax) break; 199 203 g->DrawLine(g->DeltaUCX(x,-tickLeft),yticks[i],g->DeltaUCX(x,tickRight),yticks[i]); … … 204 208 void PIAxes::DrawHLabels(PIGraphicUC* g, double y, vector<double>& xticks, unsigned long just) 205 209 { 206 207 if(xticks.size()<=1) return; 208 // Choix du bon format pour les labels des axes; 209 char label[64]; string format; double fac=1.; bool p10=false; 210 double xstep=xticks[1]-xticks[0]; 211 int npuiss = BonFormatAxes(xticks[0],xMax,xstep,format,2,1); 212 if(npuiss<-2 || npuiss>3) {p10 = true; fac=pow(10.,(double)npuiss);} 213 else BonFormatAxes(xticks[0],xMax,xstep,format,0,1); 214 215 double xOffset = 0; 216 double xlastlabelfin = xticks[0] - 2.*(xMax-xticks[0]); 210 if(xticks.size()==0) return; 211 212 // Choix du bon format pour les labels des axes 213 string format; double xstep; 214 int npuiss = Le_Bon_Format(xticks,format,xstep); 215 double fac=(npuiss!=0)? fac=pow(10.,(double)npuiss): 1.; 216 217 char label[64]; 218 double dum,xpixdeb,xpixfin,largpix; 219 g->UC2GrC(xMin-2.*(xMax-xMin),y,xpixfin,dum); 217 220 for(unsigned int i=0;i<xticks.size();i++) { 221 if(xticks[i]<xMin) continue; 218 222 if(xticks[i]>xMax) break; 219 223 //Attention erreur d'arrondi x->0 (on code 5.1698e-26 au lieu de 0) 220 224 double xx = (fabs(xticks[i]/xstep)<1.e-5) ? 0.: xticks[i]; 221 sprintf(label,format.c_str(),xx/fac); 222 Arrange_Label(label); 225 sprintf(label,format.c_str(),xx/fac); Arrange_Label(label); 223 226 double largeur = g->CalcStringWidth(label); 224 if(aXdir) xOffset = largeur/2; else xOffset=-largeur/2; 225 if(xticks[i]+xOffset > xlastlabelfin) { 227 g->DUC2GrC(largeur,0.,largpix,dum); 228 g->UC2GrC(xticks[i],y,xpixdeb,dum); xpixdeb -= largpix/2.; 229 //cout<<"xticks="<<xticks[i]<<" largpix="<<largpix 230 // <<" xpixdeb="<<xpixdeb<<" xpixfin="<<xpixfin<<endl; 231 if((aXdir && xpixdeb<xpixfin) || (!aXdir && xpixdeb>xpixfin)) { 226 232 g->DrawString(xticks[i],y,label,PI_HorizontalCenter|just); 227 x lastlabelfin = xticks[i] + xOffset + 1.1*largeur;228 } 229 } 230 231 if( p10) {233 xpixfin = xpixdeb + 1.1*largpix; 234 } 235 } 236 237 if(npuiss!=0) { 232 238 PIGrCoord asc,desc; 233 239 double h = g->GetFontHeight(asc,desc); 234 if((aYdir && (just&PI_VerticalBottom)) || (!aYdir && (just&PI_VerticalTop)) ) h =-h;240 if((aYdir && (just&PI_VerticalBottom)) || (!aYdir && (just&PI_VerticalTop))) h=-h; 235 241 double xm = (aXdir)? xMin: xMax; 236 242 double ym = g->DeltaUCY(y,1.5*h); … … 244 250 void PIAxes::DrawVLabels(PIGraphicUC* g, double x, vector<double>& yticks, unsigned long just) 245 251 { 246 247 if(yticks.size()<=1) return; 252 if(yticks.size()==0) return; 253 248 254 // Choix du bon format pour les labels des axes; 249 char label[64]; string format; double fac=1.; bool p10=false; 250 double ystep=yticks[1]-yticks[0]; 251 int npuiss = BonFormatAxes(yticks[0],yMax,ystep,format,2,1); 252 if(npuiss<-2 || npuiss>3) {p10 = true; fac=pow(10.,(double)npuiss);} 253 else BonFormatAxes(yticks[0],yMax,ystep,format,0,1); 254 255 string format; double ystep; 256 int npuiss = Le_Bon_Format(yticks,format,ystep); 257 double fac=(npuiss!=0)? fac=pow(10.,(double)npuiss): 1.; 258 259 char label[64]; 260 PIGrCoord asc,desc; 261 double dum,ypixdeb,ypixfin,hautpix,hauteur=g->GetFontHeight(asc,desc); 262 g->DUC2GrC(0.,hauteur,dum,hautpix); 263 g->UC2GrC(x,yMin-2.*(yMax-yMin),dum,ypixfin); 255 264 for(unsigned int i=0;i<yticks.size();i++) { 265 if(yticks[i]<yMin) continue; 256 266 if(yticks[i]>yMax) break; 257 267 double yy = (fabs(yticks[i]/ystep)<1.e-5) ? 0.: yticks[i]; 258 sprintf(label,format.c_str(),yy/fac); 259 Arrange_Label(label); 260 g->DrawString(x,yticks[i],label,PI_VerticalCenter|just); 261 } 262 263 if(p10) { 264 PIGrCoord asc,desc; 265 double h = g->GetFontHeight(asc,desc); 266 if(aYdir) h = -h; 267 double ym = (aYdir)? yMin: yMax; ym = g->DeltaUCY(ym,h); 268 sprintf(label,format.c_str(),yy/fac); Arrange_Label(label); 269 g->UC2GrC(x,yticks[i],dum,ypixdeb); ypixdeb -= hautpix/2.; 270 // -- Attention: ypix=0 est en haut de l'ecran 271 // (ypix croissants vers le bas de l'ecran) 272 // donc bien que yMin<yMax on a yMinPix>yMaxPix 273 //cout<<"yticks="<<yticks[i]<<" hautpix="<<hautpix 274 // <<" ypixdeb="<<ypixdeb<<" ypixfin="<<ypixfin<<endl; 275 if((aYdir && ypixdeb>ypixfin) || (!aYdir && ypixdeb<ypixfin)) { 276 g->DrawString(x,yticks[i],label,PI_VerticalCenter|just); 277 ypixfin = ypixdeb + 1.1*hautpix; 278 } 279 } 280 281 if(npuiss!=0) { 282 if(aYdir) hauteur = -hauteur; 283 double ym = (aYdir)? yMin: yMax; ym = g->DeltaUCY(ym,hauteur); 268 284 sprintf(label,"%d",npuiss); 269 285 g->DrawCompString(x,ym,"x 10",label,NULL,PI_VerticalBottom|just); … … 293 309 } 294 310 295 296 /////////////////////////////////////////////////////////////////////////// 311 //////////////////////////////////////////////////////////////////////// 312 //////////////////// METHODES STATIQUES //////////////////////////////// 313 //////////////////////////////////////////////////////////////////////// 297 314 /* --Methode-Static-- */ 298 315 void PIAxes::BestTicks(double xmin,double xmax,int nticks 299 316 ,vector<double>& majticks,vector<double>& minticks) 300 317 // *** Calcul de l'intervalle entre les ticks et de la valeur du premier tick 301 { 302 double d=xmax-xmin; if(d<1.e-100) d=1.e-100; //if (d<1.e-39) d=1.e-39; 318 // pour un axe lineaire 319 { 320 if(nticks<=0) nticks = 1; 321 322 double d=xmax-xmin; if(d<1.e-100) d=1.e-100; 303 323 double ld = log10(d); 304 324 double fld = floor( ((ld<0.)? -ld: ld) ); 305 325 double del,del0; 306 majticks.resize(0); minticks.resize(0); 307 if(ld>=0.) {fld-=1.; del0=del=pow(10.,fld);} 308 else {fld+=2.; del0=del=pow(10.,-fld);} 326 fld = (ld>=0.)? fld-2.: -(fld+2.); 327 del0 = del = pow(10.,fld); 309 328 // *** Intervalle entre les ticks 310 329 // xmin xmax d ld fld -->fld del0 311 // 1 1500 1499 3.17 3 2 10^2 312 // 1 9500 9499 3.98 3 2 10^2 313 // 1 1.005 0.005 -2.3 2 4 10^-4 314 // 1 1.995 0.995 -0.0022 0 2 10^-2 315 // - Et recherche de la valeur del={del0,2*del0,...,20*del0} 316 // telle que "nticks*del" soit le plus petit nombre ">=d" 317 // Par exemple, si nticks=10: 318 // 1-/ pour le 2sd cas ou d=9499 et del0=100 : 319 // del = 100 200 500 1000 2000 320 // nticks*del = 1000 2000 5000 10000 20000 321 // d/del = 94.9 47.4 18.9 | 9.499 4.749 ==> majt = 1000 322 // 2-/ pour le 3ieme cas ou d=5e-3 et del0=1e-4 : 323 // del = 1e-4 2e-4 5e-4 1e-3 2e-3 324 // nticks*del = 1e-3 2e-3 5e-3 1e-2 2e-2 325 // d/del = 50 25 | 10 5 2.5 ==> majt = 5e-4 326 int k=0; 327 double fac[4] = {2.,5.,10.,20.}; 328 while(d/del>(double)nticks && k<4 ) {del=fac[k]*del0; k++;} 330 // 1 1500 1499 3.17 3 1 10^1 331 // 1 9500 9499 3.98 3 1 10^1 332 // 1 1.005 0.005 -2.3 3 -5 10^-5 333 // 1 1.995 0.995 -0.0022 1 -3 10^-3 334 // - Et recherche de la valeur del={del0,2*del0,...,20*del0,...} 335 // telle que "nticks*del" soit le plus petit nombre ">=xmax-xmin" 336 double fac[9] = {2.,5.,10.,20.,50.,100.,200.,500.,1000.}; 337 for(int k=0;k<9;k++) { 338 //cout<<"BestTicks: "<<k<<" del="<<del<<" d/del="<<d/del<<"<"<<nticks<<endl; 339 if(d/del < (double)nticks) break; 340 del=fac[k]*del0; 341 } 329 342 double steptick=del; 330 343 //*** Valeur du premier tick 331 double xfirsttick = floor(xmin/steptick); if(xmin<0.) xfirsttick+=1.; 332 xfirsttick *= steptick; 344 majticks.resize(0); 345 double xfirsttick = floor(fabs(xmin)/steptick)*steptick; 346 if(xmin<0.) xfirsttick *= -1.; 333 347 if(xfirsttick<xmin) xfirsttick += steptick; 334 majticks.push_back(xfirsttick); 335 while(xfirsttick<=xmax) 336 {xfirsttick+= steptick; majticks.push_back(xfirsttick);} 348 while(xfirsttick<=xmax+steptick/10.) 349 {majticks.push_back(xfirsttick); xfirsttick+= steptick;} 337 350 //*** Gestion des ticks mineurs 338 double steptickmin = steptick/5.; 339 double xfirsttickmin = floor(xmin/steptickmin) * steptickmin; 340 if(xfirsttickmin<xmin) xfirsttickmin += steptickmin; 341 minticks.push_back(xfirsttickmin); 342 while(xfirsttickmin<=xmax) 343 {xfirsttickmin+= steptickmin; minticks.push_back(xfirsttickmin);} 351 minticks.resize(0); 352 if(majticks.size()>1) { 353 double steptickmin = steptick/5.; 354 double xfirsttickmin = majticks[0]; 355 while(xfirsttickmin<=xmax+steptickmin/10.) 356 {minticks.push_back(xfirsttickmin); xfirsttickmin+= steptickmin;} 357 } 358 } 359 /* --Methode-Static-- */ 360 void PIAxes::BestTicksLog(double xmin,double xmax,int nticks 361 ,vector<double>& majticks,vector<double>& minticks) 362 // *** Calcul des ticks pour un axe logarithmique 363 { 364 if(nticks<=0) nticks = 1; 365 //cout<<"BestTicksLog: xmin="<<xmin<<" xmax="<<xmax<<" nticks="<<nticks<<endl; 366 367 // CMV_BUG: quand on fait func 1 100 ..., Reza renvoit xmin=-0.9602 !!! 368 // Ceci est un bricolo qui permet d'obtenir un resultat moyen. 369 // A CORRIGER: pour Reza, ne pas surdimensionner la fenetre 370 // vers les xmin,ymin SI on demande une echelle log 371 // pour etre sur que xmin,ymin sera bien ce qui est demande. 372 if(xmin<=0.) { 373 cout<<"Error_BestTicksLog: xmin="<<xmin; 374 double percor=0.05; 375 // On suppose que: xmin = xmin0 - percor*(xmax0-xmin0) 376 xmin = fabs((xmin+percor*xmax)/(1.+percor)); 377 cout<<" corrected to xmin="<<xmin<<endl 378 <<" ===> First labels may be WRONG"<<endl; 379 } 380 381 // Si xmax<=0 ou si dynamique trop faible on garde BestTicks 382 if(xmax<=0. || xmax/xmin<5.) { 383 //cout<<"Choix de BestTicks xmax="<<xmax<<" xmax/xmin="<<xmax/xmin<<" <5"<<endl;; 384 BestTicks(xmin,xmax,nticks,majticks,minticks); 385 return; 386 } 387 388 int dmin=int(floor(log10(xmin))); 389 int dmax=int(floor(log10(xmax))); 390 if(dmax==dmin) dmax++; else if(dmax<dmin) dmax=dmin+1; 391 int inc = (dmax-dmin+1)/nticks; if(inc<1) inc=1; 392 //cout<<" dmin="<<dmin<<" dmax="<<dmax<<" inc="<<inc<<endl; 393 394 majticks.resize(0); 395 for(int i=dmin;i<=dmax;i+=inc) { 396 double x = pow(10.,(double)i); 397 if(x<xmin || x>xmax) continue; 398 majticks.push_back(x); 399 } 400 //cout<<"majticks.size()="<<majticks.size()<<endl; 401 402 // Pas de puissance de 10 dans l'intervalle 403 if(majticks.size()==0) { 404 BestTicks(xmin,xmax,nticks,majticks,minticks); 405 return; 406 } 407 408 // Pas suffisamment de ticks majeurs 409 if((int)majticks.size()<=nticks/2) { 410 int nins = nticks/(majticks.size()+1); 411 if(nins<=0) nins=1; 412 //cout<<"nins="<<nins<<endl; 413 // Sequence judicieuse pour remplir les ticks manquants 414 // nins = 1 on insere 3 415 // 2 2 5 416 // 3 2 4 6 417 // 4 1.5 2 4 6 418 // >=5 on reste au cas precedent 419 double seqmaj[4][4] = {{3.,0,0,0},{2.,5.,0,0},{2.,4.,6.,0},{1.5,2.,4.,6.}}; 420 if(nins>4) nins=4; 421 vector<double> tmp; 422 for(unsigned int i=0;i<=majticks.size();i++) { 423 double xt; 424 if(i<majticks.size()) xt = majticks[i]/10.; 425 else xt = majticks[i-1]; 426 for(int n=0;n<nins;n++) { 427 double xins = seqmaj[nins-1][n]*xt; 428 if(xins<xmin || xins>xmax) continue; 429 tmp.push_back(xins); 430 } 431 if(i<majticks.size()) tmp.push_back(majticks[i]); 432 } 433 majticks = tmp; 434 } 435 //cout<<"...majticks.size()="<<majticks.size()<<endl; 436 437 // Les ticks mimneurs 438 minticks.resize(0); 439 for(unsigned int i=0;i<majticks.size()-1;i++) { 440 double dx = (majticks[i+1]-majticks[i])/10.; 441 minticks.push_back(majticks[i]); 442 for(int j=2;j<=8;j+=2) { 443 double x = majticks[i] + j*dx; 444 if(x<xmin || x>xmax) continue; 445 minticks.push_back(x); 446 } 447 } 448 minticks.push_back(majticks[majticks.size()-1]); 449 //cout<<"...minticks.size()="<<minticks.size()<<endl; 450 344 451 } 345 452 … … 440 547 } 441 548 549 /* --Methode-- */ 550 int PIAxes::Le_Bon_Format(vector<double>& xticks,string& format,double& xstep) 551 // Methode static de decision du bon format 552 // Decide quel format est le mieux adapte pour ecrire les labels des axes 553 // Decide si une puissance de 10 doit etre deportee en bout d'axe 554 // - Input: 555 // xticks : vecteur des ticks a ecrire (calcule par BestTicks) 556 // - Output: 557 // format : format a utiliser 558 // xstep : step entre 2 graduations 559 // - Return: 560 // npuiss : si format choisit avec ecriture 561 // avec label des puissances de 10 deporte 562 // 0 : sinon 563 { 564 format="%g"; xstep=1.; 565 if(xticks.size()<=1) return 0; 566 567 xstep=xticks[1]-xticks[0]; 568 int npuiss = BonFormatAxes(xticks[0],xticks[xticks.size()-1],xstep,format,2,1); 569 if(npuiss>=-2 && npuiss<=3) { 570 npuiss = 0; 571 BonFormatAxes(xticks[0],xticks[xticks.size()-1],xstep,format,0,1); 572 } 573 return npuiss; 574 } 575 442 576 void PIAxes::Arrange_Label(char *label) 577 // --- Mise en forme optimale du label numerique 443 578 // Enleve les blancs et les zeros inutiles a la fin d'un label 444 579 { -
trunk/SophyaPI/PI/piaxes.h
r2088 r2091 45 45 static void BestTicks(double xmin,double xmax,int nticks 46 46 ,vector<double>& majticks,vector<double>& minticks); 47 static void BestTicksLog(double xmin,double xmax,int nticks 48 ,vector<double>& majticks,vector<double>& minticks); 47 49 48 // Calcul du format optimal pour les axes(STATIC)50 // Calcul du format optimal (STATIC) 49 51 static int BonFormatAxes(double xmin,double xmax,double xstep 50 52 ,string& format,int typf=0,int add_digit=0); 51 53 52 // Mise en forme optimale du format (STATIC) 54 // Decision du format optimal pour les axes (STATIC) 55 static int Le_Bon_Format(vector<double>& xticks,string& format,double& xstep); 56 57 // Mise en forme optimale du label numerique (STATIC) 53 58 static void Arrange_Label(char *label); 54 59 55 60 protected: 56 void Setup(PIGraphicUC* g, double xmin, double xmax, 57 double ymin, double ymax); 61 void Setup(PIGraphicUC* g,double xmin,double xmax,double ymin,double ymax); 58 62 59 63 void DrawHTicks(PIGraphicUC* g, double y, double tickUp, double tickDown, vector<double>& xticks); -
trunk/SophyaPI/PI/piversion.h
r2042 r2091 2 2 #define PIVERSION_H_SEEN 3 3 4 #define PI_VERSIONNUMBER 3.6 84 #define PI_VERSIONNUMBER 3.69 5 5 6 6 #endif
Note:
See TracChangeset
for help on using the changeset viewer.