00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "TROOT.h"
00013 #include "TGraph2DPainter.h"
00014 #include "TMath.h"
00015 #include "TList.h"
00016 #include "TGraph.h"
00017 #include "TGraph2D.h"
00018 #include "TGraphDelaunay.h"
00019 #include "TPolyLine.h"
00020 #include "TPolyMarker.h"
00021 #include "TVirtualPad.h"
00022 #include "TView.h"
00023 #include "THLimitsFinder.h"
00024 #include "TStyle.h"
00025 #include "Hoption.h"
00026 #include "TH1.h"
00027
00028 R__EXTERN TH1 *gCurrentHist;
00029 R__EXTERN Hoption_t Hoption;
00030
00031 ClassImp(TGraph2DPainter)
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 TGraph2DPainter::TGraph2DPainter()
00042 {
00043
00044
00045 fX = 0;
00046 fY = 0;
00047 fZ = 0;
00048 fEX = 0;
00049 fEY = 0;
00050 fEZ = 0;
00051 fXN = 0;
00052 fYN = 0;
00053 fPTried = 0;
00054 fNTried = 0;
00055 fMTried = 0;
00056 fGraph2D = 0;
00057 fDelaunay = 0;
00058 fXmin = 0.;
00059 fXmax = 0.;
00060 fYmin = 0.;
00061 fYmax = 0.;
00062 fZmin = 0.;
00063 fZmax = 0.;
00064 fXNmin = 0;
00065 fXNmax = 0;
00066 fYNmin = 0;
00067 fYNmax = 0;
00068 fNdt = 0;
00069 fNpoints = 0;
00070 }
00071
00072
00073
00074 TGraph2DPainter::TGraph2DPainter(TGraphDelaunay *gd)
00075 {
00076
00077
00078 fDelaunay = gd;
00079 fGraph2D = fDelaunay->GetGraph2D();
00080 fNpoints = fGraph2D->GetN();
00081 fX = fGraph2D->GetX();
00082 fY = fGraph2D->GetY();
00083 fZ = fGraph2D->GetZ();
00084 fEX = fGraph2D->GetEX();
00085 fEY = fGraph2D->GetEY();
00086 fEZ = fGraph2D->GetEZ();
00087 fNdt = 0;
00088 fXN = 0;
00089 fYN = 0;
00090 fXNmin = 0;
00091 fXNmax = 0;
00092 fYNmin = 0;
00093 fYNmax = 0;
00094 fPTried = 0;
00095 fNTried = 0;
00096 fMTried = 0;
00097 fXmin = 0.;
00098 fXmax = 0.;
00099 fYmin = 0.;
00100 fYmax = 0.;
00101 fZmin = 0.;
00102 fZmax = 0.;
00103 }
00104
00105
00106
00107 TGraph2DPainter::~TGraph2DPainter()
00108 {
00109
00110 }
00111
00112
00113
00114 void TGraph2DPainter::FindTriangles()
00115 {
00116
00117
00118
00119 fDelaunay->FindAllTriangles();
00120 fNdt = fDelaunay->GetNdt();
00121 fXN = fDelaunay->GetXN();
00122 fYN = fDelaunay->GetYN();
00123 fXNmin = fDelaunay->GetXNmin();
00124 fXNmax = fDelaunay->GetXNmax();
00125 fYNmin = fDelaunay->GetYNmin();
00126 fYNmax = fDelaunay->GetYNmax();
00127 fPTried = fDelaunay->GetPTried();
00128 fNTried = fDelaunay->GetNTried();
00129 fMTried = fDelaunay->GetMTried();
00130 }
00131
00132
00133
00134 TList *TGraph2DPainter::GetContourList(Double_t contour)
00135 {
00136
00137
00138
00139
00140
00141 Double_t zmin = gCurrentHist->GetMinimum();
00142 Double_t zmax = gCurrentHist->GetMaximum();
00143 if (Hoption.Logz) {
00144 if (zmin > 0) {
00145 zmin = TMath::Log10(zmin);
00146 zmax = TMath::Log10(zmax);
00147 } else {
00148 return 0;
00149 }
00150 }
00151 if(contour<zmin || contour>zmax) {
00152 Error("GetContourList", "Contour level (%g) outside the Z scope [%g,%g]",
00153 contour,zmin,zmax);
00154 return 0;
00155 }
00156
00157 if (!fNdt) FindTriangles();
00158
00159 TGraph *graph = 0;
00160 Int_t npg = 0;
00161 TList *list = new TList();
00162
00163
00164
00165 Double_t r21, r20, r10;
00166 Int_t p0, p1, p2;
00167 Double_t x0, y0, z0;
00168 Double_t x1, y1, z1;
00169 Double_t x2, y2, z2;
00170 Int_t t[3],i,it,i0,i1,i2;
00171
00172
00173
00174 Double_t xs0c, ys0c, xs1c, ys1c;
00175 Double_t *xs0 = new Double_t[fNdt];
00176 Double_t *ys0 = new Double_t[fNdt];
00177 Double_t *xs1 = new Double_t[fNdt];
00178 Double_t *ys1 = new Double_t[fNdt];
00179 for (i=0;i<fNdt;i++) {
00180 xs0[i] = 0.;
00181 ys0[i] = 0.;
00182 xs1[i] = 0.;
00183 ys1[i] = 0.;
00184 }
00185 Int_t nbSeg = 0;
00186
00187
00188
00189 for(it=0; it<fNdt; it++) {
00190 t[0] = fPTried[it];
00191 t[1] = fNTried[it];
00192 t[2] = fMTried[it];
00193 p0 = t[0]-1;
00194 p1 = t[1]-1;
00195 p2 = t[2]-1;
00196 x0 = fX[p0]; x2 = fX[p0];
00197 y0 = fY[p0]; y2 = fY[p0];
00198 z0 = fZ[p0]; z2 = fZ[p0];
00199
00200
00201
00202 i0=0, i1=0, i2=0;
00203 if (fZ[p1]<=z0) {z0=fZ[p1]; x0=fX[p1]; y0=fY[p1]; i0=1;}
00204 if (fZ[p1]>z2) {z2=fZ[p1]; x2=fX[p1]; y2=fY[p1]; i2=1;}
00205 if (fZ[p2]<=z0) {z0=fZ[p2]; x0=fX[p2]; y0=fY[p2]; i0=2;}
00206 if (fZ[p2]>z2) {z2=fZ[p2]; x2=fX[p2]; y2=fY[p2]; i2=2;}
00207 if (i0==0 && i2==0) {
00208 Error("GetContourList", "wrong vertices ordering");
00209 delete [] xs0;
00210 delete [] ys0;
00211 delete [] xs1;
00212 delete [] ys1;
00213 return 0;
00214 } else {
00215 i1 = 3-i2-i0;
00216 }
00217 x1 = fX[t[i1]-1];
00218 y1 = fY[t[i1]-1];
00219 z1 = fZ[t[i1]-1];
00220
00221 if (Hoption.Logz) {
00222 z0 = TMath::Log10(z0);
00223 z1 = TMath::Log10(z1);
00224 z2 = TMath::Log10(z2);
00225 }
00226
00227 if(contour >= z0 && contour <=z2) {
00228 r20 = (contour-z0)/(z2-z0);
00229 xs0c = r20*(x2-x0)+x0;
00230 ys0c = r20*(y2-y0)+y0;
00231 if(contour >= z1 && contour <=z2) {
00232 r21 = (contour-z1)/(z2-z1);
00233 xs1c = r21*(x2-x1)+x1;
00234 ys1c = r21*(y2-y1)+y1;
00235 } else {
00236 r10 = (contour-z0)/(z1-z0);
00237 xs1c = r10*(x1-x0)+x0;
00238 ys1c = r10*(y1-y0)+y0;
00239 }
00240
00241 if(xs0c != xs1c || ys0c != ys1c) {
00242 nbSeg++;
00243 xs0[nbSeg-1] = xs0c;
00244 ys0[nbSeg-1] = ys0c;
00245 xs1[nbSeg-1] = xs1c;
00246 ys1[nbSeg-1] = ys1c;
00247 }
00248 }
00249 }
00250
00251 Bool_t *segUsed = new Bool_t[fNdt];
00252 for(i=0; i<fNdt; i++) segUsed[i]=kFALSE;
00253
00254
00255
00256
00257
00258 Double_t xc=0, yc=0, xnc=0, ync=0;
00259 Bool_t findNew;
00260 Bool_t s0, s1;
00261 Int_t is, js;
00262 for (is=0; is<nbSeg; is++) {
00263 if (segUsed[is]) continue;
00264 s0 = s1 = kFALSE;
00265
00266
00267
00268 for (js=0; js<nbSeg; js++) {
00269 if (is==js) continue;
00270 if (xs0[is]==xs0[js] && ys0[is]==ys0[js]) s0 = kTRUE;
00271 if (xs0[is]==xs1[js] && ys0[is]==ys1[js]) s0 = kTRUE;
00272 if (xs1[is]==xs0[js] && ys1[is]==ys0[js]) s1 = kTRUE;
00273 if (xs1[is]==xs1[js] && ys1[is]==ys1[js]) s1 = kTRUE;
00274 }
00275
00276
00277
00278 if (!s0 && !s1) {
00279 graph = new TGraph();
00280 graph->SetPoint(npg,xs0[is],ys0[is]); npg++;
00281 graph->SetPoint(npg,xs1[is],ys1[is]); npg++;
00282 segUsed[is] = kTRUE;
00283 list->Add(graph); npg = 0;
00284 continue;
00285 }
00286
00287
00288
00289 if (!s0 || !s1) {
00290
00291 graph = new TGraph();
00292 if (s0) {xc = xs0[is]; yc = ys0[is]; xnc = xs1[is]; ync = ys1[is];}
00293 if (s1) {xc = xs1[is]; yc = ys1[is]; xnc = xs0[is]; ync = ys0[is];}
00294 graph->SetPoint(npg,xnc,ync); npg++;
00295 segUsed[is] = kTRUE;
00296 js = 0;
00297 L01:
00298 findNew = kFALSE;
00299 if (segUsed[js] && js<nbSeg) {
00300 js++;
00301 goto L01;
00302 } else if (xc==xs0[js] && yc==ys0[js]) {
00303 xc = xs1[js];
00304 yc = ys1[js];
00305 findNew = kTRUE;
00306 } else if (xc==xs1[js] && yc==ys1[js]) {
00307 xc = xs0[js];
00308 yc = ys0[js];
00309 findNew = kTRUE;
00310 }
00311 if (findNew) {
00312 segUsed[js] = kTRUE;
00313 graph->SetPoint(npg,xc,yc); npg++;
00314 js = 0;
00315 goto L01;
00316 }
00317 js++;
00318 if (js<nbSeg) goto L01;
00319 list->Add(graph); npg = 0;
00320 }
00321 }
00322
00323
00324
00325 for (is=0; is<nbSeg; is++) {
00326 if (segUsed[is]) continue;
00327
00328
00329 graph = new TGraph();
00330 segUsed[is] = kTRUE;
00331 xc = xs0[is];
00332 yc = ys0[is];
00333 js = 0;
00334 graph->SetPoint(npg,xc,yc); npg++;
00335 L02:
00336 findNew = kFALSE;
00337 if (segUsed[js] && js<nbSeg) {
00338 js++;
00339 goto L02;
00340 } else if (xc==xs0[js] && yc==ys0[js]) {
00341 xc = xs1[js];
00342 yc = ys1[js];
00343 findNew = kTRUE;
00344 } else if (xc==xs1[js] && yc==ys1[js]) {
00345 xc = xs0[js];
00346 yc = ys0[js];
00347 findNew = kTRUE;
00348 }
00349 if (findNew) {
00350 segUsed[js] = kTRUE;
00351 graph->SetPoint(npg,xc,yc); npg++;
00352 js = 0;
00353 goto L02;
00354 }
00355 js++;
00356 if (js<nbSeg) goto L02;
00357
00358 graph->SetPoint(npg,xs0[is],ys0[is]); npg++;
00359 list->Add(graph); npg = 0;
00360 }
00361
00362 delete [] xs0;
00363 delete [] ys0;
00364 delete [] xs1;
00365 delete [] ys1;
00366 delete [] segUsed;
00367 return list;
00368 }
00369
00370
00371
00372 void TGraph2DPainter::Paint(Option_t *option)
00373 {
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391 TString opt = option;
00392 opt.ToLower();
00393 Bool_t triangles = opt.Contains("tri") ||
00394 opt.Contains("tri1") ||
00395 opt.Contains("tri2");
00396 if (opt.Contains("tri0")) triangles = kFALSE;
00397
00398 Bool_t markers = opt.Contains("p") && !triangles;
00399 Bool_t contour = opt.Contains("cont");
00400 Bool_t line = opt.Contains("line");
00401 Bool_t err = opt.Contains("err");
00402
00403 fGraph2D->TAttLine::Modify();
00404 fGraph2D->TAttFill::Modify();
00405 fGraph2D->TAttMarker::Modify();
00406
00407
00408 TAxis *xaxis = gCurrentHist->GetXaxis();
00409 Int_t first = xaxis->GetFirst();
00410 fXmin = xaxis->GetBinLowEdge(first);
00411 if (Hoption.Logx && fXmin <= 0) fXmin = xaxis->GetBinUpEdge(xaxis->FindFixBin(0.01*xaxis->GetBinWidth(first)));
00412 fXmax = xaxis->GetBinUpEdge(xaxis->GetLast());
00413 TAxis *yaxis = gCurrentHist->GetYaxis();
00414 first = yaxis->GetFirst();
00415 fYmin = yaxis->GetBinLowEdge(first);
00416 if (Hoption.Logy && fYmin <= 0) fYmin = yaxis->GetBinUpEdge(yaxis->FindFixBin(0.01*yaxis->GetBinWidth(first)));
00417 fYmax = yaxis->GetBinUpEdge(yaxis->GetLast());
00418 fZmax = fGraph2D->GetZmax();
00419 fZmin = fGraph2D->GetZmin();
00420 if (Hoption.Logz && fZmin <= 0) fZmin = TMath::Min((Double_t)1, (Double_t)0.001*fGraph2D->GetZmax());
00421
00422 if (triangles) PaintTriangles(option);
00423 if (contour) PaintContour(option);
00424 if (line) PaintPolyLine(option);
00425 if (err) PaintErrors(option);
00426 if (markers) PaintPolyMarker(option);
00427 }
00428
00429
00430
00431 void TGraph2DPainter::PaintContour(Option_t * )
00432 {
00433
00434
00435
00436
00437 Int_t ncolors = gStyle->GetNumberOfColors();
00438 Int_t ndiv = gCurrentHist->GetContour();
00439 if (ndiv == 0 ) {
00440 ndiv = gStyle->GetNumberContours();
00441 gCurrentHist->SetContour(ndiv);
00442 }
00443 Int_t ndivz = TMath::Abs(ndiv);
00444 if (gCurrentHist->TestBit(TH1::kUserContour) == 0) gCurrentHist->SetContour(ndiv);
00445
00446 Int_t theColor;
00447 TList *l;
00448 TGraph *g;
00449 TObject *obj;
00450 Double_t c;
00451
00452 if (!fNdt) FindTriangles();
00453
00454 for (Int_t k=0; k<ndiv; k++) {
00455 c = gCurrentHist->GetContourLevelPad(k);
00456 l = GetContourList(c);
00457 TIter next(l);
00458 while ((obj = next())) {
00459 if(obj->InheritsFrom(TGraph::Class()) ) {
00460 g=(TGraph*)obj;
00461 theColor = Int_t((k+0.99)*Float_t(ncolors)/Float_t(ndivz));
00462 g->SetLineColor(gStyle->GetColorPalette(theColor));
00463 g->Paint("l");
00464 }
00465 }
00466 }
00467 }
00468
00469
00470
00471 void TGraph2DPainter::PaintErrors(Option_t * )
00472 {
00473
00474
00475 Double_t temp1[3],temp2[3];
00476
00477 TView *view = gPad->GetView();
00478 if (!view) {
00479 Error("PaintErrors", "No TView in current pad");
00480 return;
00481 }
00482
00483 Int_t it;
00484
00485 Double_t *xm = new Double_t[2];
00486 Double_t *ym = new Double_t[2];
00487
00488 fGraph2D->SetLineStyle(fGraph2D->GetLineStyle());
00489 fGraph2D->SetLineWidth(fGraph2D->GetLineWidth());
00490 fGraph2D->SetLineColor(fGraph2D->GetLineColor());
00491 fGraph2D->TAttLine::Modify();
00492
00493 for (it=0; it<fNpoints; it++) {
00494 if(fX[it] < fXmin || fX[it] > fXmax) continue;
00495 if(fY[it] < fYmin || fY[it] > fYmax) continue;
00496 if (fEX) {
00497 temp1[0] = fX[it]-fEX[it];
00498 temp1[1] = fY[it];
00499 temp1[2] = fZ[it];
00500 temp1[0] = TMath::Max(temp1[0],fXmin);
00501 temp1[1] = TMath::Max(temp1[1],fYmin);
00502 temp1[2] = TMath::Max(temp1[2],fZmin);
00503 temp1[2] = TMath::Min(temp1[2],fZmax);
00504 if (Hoption.Logx) temp1[0] = TMath::Log10(temp1[0]);
00505 if (Hoption.Logy) temp1[1] = TMath::Log10(temp1[1]);
00506 if (Hoption.Logz) temp1[2] = TMath::Log10(temp1[2]);
00507 view->WCtoNDC(temp1, &temp2[0]);
00508 xm[0] = temp2[0];
00509 ym[0] = temp2[1];
00510
00511 temp1[0] = fX[it]+fEX[it];
00512 temp1[0] = TMath::Max(temp1[0],fXmin);
00513 if (Hoption.Logx) temp1[0] = TMath::Log10(temp1[0]);
00514 view->WCtoNDC(temp1, &temp2[0]);
00515 xm[1] = temp2[0];
00516 ym[1] = temp2[1];
00517 gPad->PaintPolyLine(2,xm,ym);
00518 }
00519 if (fEY) {
00520 temp1[0] = fX[it];
00521 temp1[1] = fY[it]-fEY[it];
00522 temp1[2] = fZ[it];
00523 temp1[0] = TMath::Max(temp1[0],fXmin);
00524 temp1[1] = TMath::Max(temp1[1],fYmin);
00525 temp1[2] = TMath::Max(temp1[2],fZmin);
00526 temp1[2] = TMath::Min(temp1[2],fZmax);
00527 if (Hoption.Logx) temp1[0] = TMath::Log10(temp1[0]);
00528 if (Hoption.Logy) temp1[1] = TMath::Log10(temp1[1]);
00529 if (Hoption.Logz) temp1[2] = TMath::Log10(temp1[2]);
00530 view->WCtoNDC(temp1, &temp2[0]);
00531 xm[0] = temp2[0];
00532 ym[0] = temp2[1];
00533
00534 temp1[1] = fY[it]+fEY[it];
00535 temp1[1] = TMath::Max(temp1[1],fYmin);
00536 if (Hoption.Logy) temp1[1] = TMath::Log10(temp1[1]);
00537 view->WCtoNDC(temp1, &temp2[0]);
00538 xm[1] = temp2[0];
00539 ym[1] = temp2[1];
00540 gPad->PaintPolyLine(2,xm,ym);
00541 }
00542 if (fEZ) {
00543 temp1[0] = fX[it];
00544 temp1[1] = fY[it];
00545 temp1[2] = fZ[it]-fEZ[it];
00546 temp1[0] = TMath::Max(temp1[0],fXmin);
00547 temp1[1] = TMath::Max(temp1[1],fYmin);
00548 temp1[2] = TMath::Max(temp1[2],fZmin);
00549 temp1[2] = TMath::Min(temp1[2],fZmax);
00550 if (Hoption.Logx) temp1[0] = TMath::Log10(temp1[0]);
00551 if (Hoption.Logy) temp1[1] = TMath::Log10(temp1[1]);
00552 if (Hoption.Logz) temp1[2] = TMath::Log10(temp1[2]);
00553 view->WCtoNDC(temp1, &temp2[0]);
00554 xm[0] = temp2[0];
00555 ym[0] = temp2[1];
00556
00557 temp1[2] = fZ[it]+fEZ[it];
00558 temp1[2] = TMath::Max(temp1[2],fZmin);
00559 temp1[2] = TMath::Min(temp1[2],fZmax);
00560 if (Hoption.Logz) temp1[2] = TMath::Log10(temp1[2]);
00561 view->WCtoNDC(temp1, &temp2[0]);
00562 xm[1] = temp2[0];
00563 ym[1] = temp2[1];
00564 gPad->PaintPolyLine(2,xm,ym);
00565 }
00566 }
00567 delete [] xm;
00568 delete [] ym;
00569 }
00570
00571
00572
00573 void TGraph2DPainter::PaintLevels(Int_t *t,Double_t *x, Double_t *y,
00574 Int_t nblev, Double_t *glev)
00575 {
00576
00577
00578
00579
00580 Int_t i, fillColor, ncolors, theColor0, theColor2;
00581
00582 Int_t p0=t[0]-1;
00583 Int_t p1=t[1]-1;
00584 Int_t p2=t[2]-1;
00585 Double_t xl[2],yl[2];
00586 Double_t zl, r21, r20, r10;
00587 Double_t x0 = x[0] , x2 = x[0];
00588 Double_t y0 = y[0] , y2 = y[0];
00589 Double_t z0 = fZ[p0], z2 = fZ[p0];
00590 Double_t zmin = fZmin;
00591 Double_t zmax = fZmax;
00592
00593
00594
00595 Int_t i0=0, i1=0, i2=0;
00596 if (fZ[p1]<=z0) {z0=fZ[p1]; x0=x[1]; y0=y[1]; i0=1;}
00597 if (fZ[p1]>z2) {z2=fZ[p1]; x2=x[1]; y2=y[1]; i2=1;}
00598 if (fZ[p2]<=z0) {z0=fZ[p2]; x0=x[2]; y0=y[2]; i0=2;}
00599 if (fZ[p2]>z2) {z2=fZ[p2]; x2=x[2]; y2=y[2]; i2=2;}
00600 i1 = 3-i2-i0;
00601 Double_t x1 = x[i1];
00602 Double_t y1 = y[i1];
00603 Double_t z1 = fZ[t[i1]-1];
00604
00605 if (z0>zmax) z0 = zmax;
00606 if (z2>zmax) z2 = zmax;
00607 if (z0<zmin) z0 = zmin;
00608 if (z2<zmin) z2 = zmin;
00609 if (z1>zmax) z1 = zmax;
00610 if (z1<zmin) z1 = zmin;
00611
00612 if (Hoption.Logz) {
00613 z0 = TMath::Log10(z0);
00614 z1 = TMath::Log10(z1);
00615 z2 = TMath::Log10(z2);
00616 zmin = TMath::Log10(zmin);
00617 zmax = TMath::Log10(zmax);
00618 }
00619
00620
00621
00622 Double_t zi=0, zip=0;
00623
00624 if (nblev <= 0) {
00625
00626
00627
00628 ncolors = gStyle->GetNumberOfColors();
00629 theColor0 = (Int_t)( ((z0-zmin)/(zmax-zmin))*(ncolors-1) );
00630 theColor2 = (Int_t)( ((z2-zmin)/(zmax-zmin))*(ncolors-1) );
00631
00632
00633 Double_t xp[5], yp[5];
00634
00635
00636
00637 Double_t rl,rs;
00638
00639
00640
00641 Int_t ci,npf;
00642
00643 fillColor = fGraph2D->GetFillColor();
00644
00645
00646
00647 if(theColor0 == theColor2) {
00648 fGraph2D->SetFillColor(gStyle->GetColorPalette(theColor0));
00649 fGraph2D->TAttFill::Modify();
00650 gPad->PaintFillArea(3,x,y);
00651
00652
00653 } else {
00654 for(ci=theColor0; ci<=theColor2; ci++) {
00655 fGraph2D->SetFillColor(gStyle->GetColorPalette(ci));
00656 fGraph2D->TAttFill::Modify();
00657 if (ci==theColor0) {
00658 zi = (((ci+1)*(zmax-zmin))/(ncolors-1))+zmin;
00659 xp[0] = x0;
00660 yp[0] = y0;
00661 rl = (zi-z0)/(z2-z0);
00662 xp[1] = rl*(x2-x0)+x0;
00663 yp[1] = rl*(y2-y0)+y0;
00664 if (zi>=z1 || z0==z1) {
00665 rs = (zi-z1)/(z2-z1);
00666 xp[2] = rs*(x2-x1)+x1;
00667 yp[2] = rs*(y2-y1)+y1;
00668 xp[3] = x1;
00669 yp[3] = y1;
00670 npf = 4;
00671 } else {
00672 rs = (zi-z0)/(z1-z0);
00673 xp[2] = rs*(x1-x0)+x0;
00674 yp[2] = rs*(y1-y0)+y0;
00675 npf = 3;
00676 }
00677 } else if (ci==theColor2) {
00678 xp[0] = xp[1];
00679 yp[0] = yp[1];
00680 xp[1] = x2;
00681 yp[1] = y2;
00682 if (zi<z1 || z2==z1) {
00683 xp[3] = xp[2];
00684 yp[3] = yp[2];
00685 xp[2] = x1;
00686 yp[2] = y1;
00687 npf = 4;
00688 } else {
00689 npf = 3;
00690 }
00691 } else {
00692 zi = (((ci+1)*(zmax-zmin))/(ncolors-1))+zmin;
00693 xp[0] = xp[1];
00694 yp[0] = yp[1];
00695 rl = (zi-z0)/(z2-z0);
00696 xp[1] = rl*(x2-x0)+x0;
00697 yp[1] = rl*(y2-y0)+y0;
00698 if ( zi>=z1 && zip<=z1) {
00699 xp[3] = x1;
00700 yp[3] = y1;
00701 xp[4] = xp[2];
00702 yp[4] = yp[2];
00703 npf = 5;
00704 } else {
00705 xp[3] = xp[2];
00706 yp[3] = yp[2];
00707 npf = 4;
00708 }
00709 if (zi<z1) {
00710 rs = (zi-z0)/(z1-z0);
00711 xp[2] = rs*(x1-x0)+x0;
00712 yp[2] = rs*(y1-y0)+y0;
00713 } else {
00714 rs = (zi-z1)/(z2-z1);
00715 xp[2] = rs*(x2-x1)+x1;
00716 yp[2] = rs*(y2-y1)+y1;
00717 }
00718 }
00719 zip = zi;
00720
00721 gPad->PaintFillArea(npf,xp,yp);
00722 }
00723 }
00724 fGraph2D->SetFillColor(fillColor);
00725 fGraph2D->TAttFill::Modify();
00726
00727 } else {
00728
00729 fGraph2D->SetLineStyle(3);
00730 fGraph2D->TAttLine::Modify();
00731 for(i=0; i<nblev; i++){
00732 zl=glev[i];
00733 if(zl >= z0 && zl <=z2) {
00734 r21=(zl-z1)/(z2-z1);
00735 r20=(zl-z0)/(z2-z0);
00736 r10=(zl-z0)/(z1-z0);
00737 xl[0]=r20*(x2-x0)+x0;
00738 yl[0]=r20*(y2-y0)+y0;
00739 if(zl >= z1 && zl <=z2) {
00740 xl[1]=r21*(x2-x1)+x1;
00741 yl[1]=r21*(y2-y1)+y1;
00742 } else {
00743 xl[1]=r10*(x1-x0)+x0;
00744 yl[1]=r10*(y1-y0)+y0;
00745 }
00746 gPad->PaintPolyLine(2,xl,yl);
00747 }
00748 }
00749 fGraph2D->SetLineStyle(1);
00750 fGraph2D->TAttLine::Modify();
00751 }
00752 }
00753
00754
00755
00756 void TGraph2DPainter::PaintPolyMarker(Option_t *option)
00757 {
00758
00759
00760 Double_t temp1[3],temp2[3];
00761
00762 TView *view = gPad->GetView();
00763 if (!view) {
00764 Error("PaintPolyMarker", "No TView in current pad");
00765 return;
00766 }
00767
00768 TString opt = option;
00769 opt.ToLower();
00770 Bool_t markers0 = opt.Contains("p0");
00771 Bool_t colors = opt.Contains("pcol");
00772 Int_t ncolors = gStyle->GetNumberOfColors();
00773 Int_t it, theColor;
00774
00775 Double_t *xm = new Double_t[fNpoints];
00776 Double_t *ym = new Double_t[fNpoints];
00777 Int_t npd = 0;
00778 for (it=0; it<fNpoints; it++) {
00779 xm[it] = 0;
00780 ym[it] = 0;
00781 if(fX[it] < fXmin || fX[it] > fXmax) continue;
00782 if(fY[it] < fYmin || fY[it] > fYmax) continue;
00783 npd++;
00784 temp1[0] = fX[it];
00785 temp1[1] = fY[it];
00786 temp1[2] = fZ[it];
00787 temp1[0] = TMath::Max(temp1[0],fXmin);
00788 temp1[1] = TMath::Max(temp1[1],fYmin);
00789 temp1[2] = TMath::Max(temp1[2],fZmin);
00790 temp1[2] = TMath::Min(temp1[2],fZmax);
00791 if (Hoption.Logx) temp1[0] = TMath::Log10(temp1[0]);
00792 if (Hoption.Logy) temp1[1] = TMath::Log10(temp1[1]);
00793 if (Hoption.Logz) temp1[2] = TMath::Log10(temp1[2]);
00794 view->WCtoNDC(temp1, &temp2[0]);
00795 xm[it] = temp2[0];
00796 ym[it] = temp2[1];
00797 }
00798 if (markers0) {
00799 PaintPolyMarker0(npd,xm,ym);
00800 } else if (colors) {
00801 for (it=0; it<fNpoints; it++) {
00802 theColor = (Int_t)( ((fZ[it]-fZmin)/(fZmax-fZmin))*(ncolors-1) );
00803 fGraph2D->SetMarkerColor(gStyle->GetColorPalette(theColor));
00804 fGraph2D->TAttMarker::Modify();
00805 gPad->PaintPolyMarker(1,&xm[it],&ym[it]);
00806 }
00807 } else {
00808 fGraph2D->SetMarkerStyle(fGraph2D->GetMarkerStyle());
00809 fGraph2D->SetMarkerSize(fGraph2D->GetMarkerSize());
00810 fGraph2D->SetMarkerColor(fGraph2D->GetMarkerColor());
00811 fGraph2D->TAttMarker::Modify();
00812 gPad->PaintPolyMarker(npd,xm,ym);
00813 }
00814 delete [] xm;
00815 delete [] ym;
00816 }
00817
00818
00819
00820 void TGraph2DPainter::PaintPolyLine(Option_t * )
00821 {
00822
00823
00824 Double_t temp1[3],temp2[3];
00825
00826 TView *view = gPad->GetView();
00827 if (!view) {
00828 Error("PaintPolyLine", "No TView in current pad");
00829 return;
00830 }
00831
00832 Int_t it;
00833
00834 Double_t *xm = new Double_t[fNpoints];
00835 Double_t *ym = new Double_t[fNpoints];
00836 Int_t npd = 0;
00837 for (it=0; it<fNpoints; it++) {
00838 if(fX[it] < fXmin || fX[it] > fXmax) continue;
00839 if(fY[it] < fYmin || fY[it] > fYmax) continue;
00840 npd++;
00841 temp1[0] = fX[it];
00842 temp1[1] = fY[it];
00843 temp1[2] = fZ[it];
00844 temp1[0] = TMath::Max(temp1[0],fXmin);
00845 temp1[1] = TMath::Max(temp1[1],fYmin);
00846 temp1[2] = TMath::Max(temp1[2],fZmin);
00847 temp1[2] = TMath::Min(temp1[2],fZmax);
00848 if (Hoption.Logx) temp1[0] = TMath::Log10(temp1[0]);
00849 if (Hoption.Logy) temp1[1] = TMath::Log10(temp1[1]);
00850 if (Hoption.Logz) temp1[2] = TMath::Log10(temp1[2]);
00851 view->WCtoNDC(temp1, &temp2[0]);
00852 xm[it] = temp2[0];
00853 ym[it] = temp2[1];
00854 }
00855 fGraph2D->SetLineStyle(fGraph2D->GetLineStyle());
00856 fGraph2D->SetLineWidth(fGraph2D->GetLineWidth());
00857 fGraph2D->SetLineColor(fGraph2D->GetLineColor());
00858 fGraph2D->TAttLine::Modify();
00859 gPad->PaintPolyLine(npd,xm,ym);
00860 delete [] xm;
00861 delete [] ym;
00862 }
00863
00864
00865
00866 void TGraph2DPainter::PaintPolyMarker0(Int_t n, Double_t *x, Double_t *y)
00867 {
00868
00869
00870 fGraph2D->SetMarkerSize(fGraph2D->GetMarkerSize());
00871 Int_t mc = fGraph2D->GetMarkerColor();
00872 for (Int_t i=0; i<n; i++) {
00873 fGraph2D->SetMarkerStyle(20);
00874 fGraph2D->SetMarkerColor(0);
00875 fGraph2D->TAttMarker::Modify();
00876 gPad->PaintPolyMarker(1,&x[i],&y[i]);
00877 fGraph2D->SetMarkerStyle(24);
00878 fGraph2D->SetMarkerColor(mc);
00879 fGraph2D->TAttMarker::Modify();
00880 gPad->PaintPolyMarker(1,&x[i],&y[i]);
00881 }
00882 }
00883
00884
00885
00886 void TGraph2DPainter::PaintTriangles(Option_t *option)
00887 {
00888
00889
00890 Double_t x[4], y[4], temp1[3],temp2[3];
00891 Int_t it,t[3];
00892 Int_t *order = 0;
00893 Double_t *dist = 0;
00894
00895 TView *view = gPad->GetView();
00896 if (!view) {
00897 Error("PaintTriangles", "No TView in current pad");
00898 return;
00899 }
00900
00901 TString opt = option;
00902 opt.ToLower();
00903 Bool_t tri1 = opt.Contains("tri1");
00904 Bool_t tri2 = opt.Contains("tri2");
00905 Bool_t markers = opt.Contains("p");
00906 Bool_t markers0 = opt.Contains("p0");
00907 Bool_t wire = opt.Contains("w");
00908
00909
00910
00911 Int_t nblev=0;
00912 Double_t *glev=0;
00913 if (!tri1 && !tri2 && !wire) {
00914 Int_t ndivz = gCurrentHist->GetZaxis()->GetNdivisions()%100;
00915 Int_t nbins;
00916 Double_t binLow, binHigh, binWidth;
00917
00918
00919 Double_t *r0 = view->GetRmin();
00920 Double_t *r1 = view->GetRmax();
00921
00922 if (ndivz > 0) {
00923 THLimitsFinder::Optimize(r0[2], r1[2], ndivz,
00924 binLow, binHigh, nbins, binWidth, " ");
00925 } else {
00926 nbins = TMath::Abs(ndivz);
00927 binLow = r0[2];
00928 binHigh = r1[2];
00929 binWidth = (binHigh-binLow)/nbins;
00930 }
00931
00932 nblev = nbins+1;
00933 glev = new Double_t[nblev];
00934 for (Int_t i = 0; i < nblev; ++i) glev[i] = binLow+i*binWidth;
00935 }
00936
00937
00938 if (tri1 || tri2) {
00939 Int_t ndiv = gCurrentHist->GetContour();
00940 if (ndiv == 0 ) {
00941 ndiv = gStyle->GetNumberContours();
00942 gCurrentHist->SetContour(ndiv);
00943 }
00944 if (gCurrentHist->TestBit(TH1::kUserContour) == 0) gCurrentHist->SetContour(ndiv);
00945 }
00946
00947
00948
00949
00950 if (!fNdt) FindTriangles();
00951 Double_t cp = TMath::Cos(view->GetLongitude()*TMath::Pi()/180.);
00952 Double_t sp = TMath::Sin(view->GetLongitude()*TMath::Pi()/180.);
00953 order = new Int_t[fNdt];
00954 dist = new Double_t[fNdt];
00955 Double_t xd,yd;
00956 Int_t p, n, m;
00957 Bool_t o = kFALSE;
00958 for (it=0; it<fNdt; it++) {
00959 p = fPTried[it];
00960 n = fNTried[it];
00961 m = fMTried[it];
00962 xd = (fXN[p]+fXN[n]+fXN[m])/3;
00963 yd = (fYN[p]+fYN[n]+fYN[m])/3;
00964 if ((cp >= 0) && (sp >= 0.)) {
00965 dist[it] = -(fXNmax-xd+fYNmax-yd);
00966 } else if ((cp <= 0) && (sp >= 0.)) {
00967 dist[it] = -(fXNmax-xd+yd-fYNmin);
00968 o = kTRUE;
00969 } else if ((cp <= 0) && (sp <= 0.)) {
00970 dist[it] = -(xd-fXNmin+yd-fYNmin);
00971 } else {
00972 dist[it] = -(xd-fXNmin+fYNmax-yd);
00973 o = kTRUE;
00974 }
00975 }
00976 TMath::Sort(fNdt, dist, order, o);
00977
00978
00979 fGraph2D->SetFillColor(fGraph2D->GetFillColor());
00980 Int_t fs = fGraph2D->GetFillStyle();
00981 fGraph2D->SetFillStyle(1001);
00982 fGraph2D->TAttFill::Modify();
00983 fGraph2D->SetLineColor(fGraph2D->GetLineColor());
00984 fGraph2D->TAttLine::Modify();
00985 int lst = fGraph2D->GetLineStyle();
00986 for (it=0; it<fNdt; it++) {
00987 t[0] = fPTried[order[it]];
00988 t[1] = fNTried[order[it]];
00989 t[2] = fMTried[order[it]];
00990 for (Int_t k=0; k<3; k++) {
00991 if(fX[t[k]-1] < fXmin || fX[t[k]-1] > fXmax) goto endloop;
00992 if(fY[t[k]-1] < fYmin || fY[t[k]-1] > fYmax) goto endloop;
00993 temp1[0] = fX[t[k]-1];
00994 temp1[1] = fY[t[k]-1];
00995 temp1[2] = fZ[t[k]-1];
00996 temp1[0] = TMath::Max(temp1[0],fXmin);
00997 temp1[1] = TMath::Max(temp1[1],fYmin);
00998 temp1[2] = TMath::Max(temp1[2],fZmin);
00999 temp1[2] = TMath::Min(temp1[2],fZmax);
01000 if (Hoption.Logx) temp1[0] = TMath::Log10(temp1[0]);
01001 if (Hoption.Logy) temp1[1] = TMath::Log10(temp1[1]);
01002 if (Hoption.Logz) temp1[2] = TMath::Log10(temp1[2]);
01003 view->WCtoNDC(temp1, &temp2[0]);
01004 x[k] = temp2[0];
01005 y[k] = temp2[1];
01006 }
01007 x[3] = x[0];
01008 y[3] = y[0];
01009 if (tri1 || tri2) PaintLevels(t,x,y);
01010 if (!tri1 && !tri2 && !wire) {
01011 gPad->PaintFillArea(3,x,y);
01012 PaintLevels(t,x,y,nblev,glev);
01013 }
01014 if (!tri2) gPad->PaintPolyLine(4,x,y);
01015 if (markers) {
01016 if (markers0) {
01017 PaintPolyMarker0(3,x,y);
01018 } else {
01019 fGraph2D->SetMarkerStyle(fGraph2D->GetMarkerStyle());
01020 fGraph2D->SetMarkerSize(fGraph2D->GetMarkerSize());
01021 fGraph2D->SetMarkerColor(fGraph2D->GetMarkerColor());
01022 fGraph2D->TAttMarker::Modify();
01023 gPad->PaintPolyMarker(3,x,y);
01024 }
01025 }
01026 endloop:
01027 continue;
01028 }
01029 fGraph2D->SetFillStyle(fs);
01030 fGraph2D->SetLineStyle(lst);
01031 fGraph2D->TAttLine::Modify();
01032 fGraph2D->TAttFill::Modify();
01033 delete [] order;
01034 delete [] dist;
01035 if (glev) delete [] glev;
01036 }