// @(#)root/histpainter:$Id: TGraph2DPainter.cxx,v 1.00 // Author: Olivier Couet /************************************************************************* * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. * * All rights reserved. * * * * For the licensing terms see $ROOTSYS/LICENSE. * * For the list of contributors see $ROOTSYS/README/CREDITS. * *************************************************************************/ #include "TROOT.h" #include "TGraph2DPainter.h" #include "TMath.h" #include "TList.h" #include "TGraph.h" #include "TGraph2D.h" #include "TGraphDelaunay.h" #include "TPolyLine.h" #include "TPolyMarker.h" #include "TVirtualPad.h" #include "TView.h" #include "THLimitsFinder.h" #include "TStyle.h" #include "Hoption.h" #include "TH1.h" R__EXTERN TH1 *gCurrentHist; R__EXTERN Hoption_t Hoption; ClassImp(TGraph2DPainter) //______________________________________________________________________________ // // TGraph2DPainter paints a TGraphDelaunay // //______________________________________________________________________________ TGraph2DPainter::TGraph2DPainter() { // TGraph2DPainter default constructor fX = 0; fY = 0; fZ = 0; fEX = 0; fEY = 0; fEZ = 0; fXN = 0; fYN = 0; fPTried = 0; fNTried = 0; fMTried = 0; fGraph2D = 0; fDelaunay = 0; fXmin = 0.; fXmax = 0.; fYmin = 0.; fYmax = 0.; fZmin = 0.; fZmax = 0.; fXNmin = 0; fXNmax = 0; fYNmin = 0; fYNmax = 0; fNdt = 0; fNpoints = 0; } //______________________________________________________________________________ TGraph2DPainter::TGraph2DPainter(TGraphDelaunay *gd) { // TGraph2DPainter constructor fDelaunay = gd; fGraph2D = fDelaunay->GetGraph2D(); fNpoints = fGraph2D->GetN(); fX = fGraph2D->GetX(); fY = fGraph2D->GetY(); fZ = fGraph2D->GetZ(); fEX = fGraph2D->GetEX(); fEY = fGraph2D->GetEY(); fEZ = fGraph2D->GetEZ(); fNdt = 0; fXN = 0; fYN = 0; fXNmin = 0; fXNmax = 0; fYNmin = 0; fYNmax = 0; fPTried = 0; fNTried = 0; fMTried = 0; fXmin = 0.; fXmax = 0.; fYmin = 0.; fYmax = 0.; fZmin = 0.; fZmax = 0.; } //______________________________________________________________________________ TGraph2DPainter::~TGraph2DPainter() { // TGraph2DPainter destructor. } //______________________________________________________________________________ void TGraph2DPainter::FindTriangles() { // Find triangles in fDelaunay and initialise the TGraph2DPainter values // needed to paint triangles or find contours. fDelaunay->FindAllTriangles(); fNdt = fDelaunay->GetNdt(); fXN = fDelaunay->GetXN(); fYN = fDelaunay->GetYN(); fXNmin = fDelaunay->GetXNmin(); fXNmax = fDelaunay->GetXNmax(); fYNmin = fDelaunay->GetYNmin(); fYNmax = fDelaunay->GetYNmax(); fPTried = fDelaunay->GetPTried(); fNTried = fDelaunay->GetNTried(); fMTried = fDelaunay->GetMTried(); } //______________________________________________________________________________ TList *TGraph2DPainter::GetContourList(Double_t contour) { // Returns the X and Y graphs building a contour. A contour level may // consist in several parts not connected to each other. This function // finds them and returns them in a graphs' list. // Exit if the contour is outisde the Z range. Double_t zmin = gCurrentHist->GetMinimum(); Double_t zmax = gCurrentHist->GetMaximum(); if (Hoption.Logz) { if (zmin > 0) { zmin = TMath::Log10(zmin); zmax = TMath::Log10(zmax); } else { return 0; } } if(contourzmax) { Error("GetContourList", "Contour level (%g) outside the Z scope [%g,%g]", contour,zmin,zmax); return 0; } if (!fNdt) FindTriangles(); TGraph *graph = 0; // current graph Int_t npg = 0; // number of points in the current graph TList *list = new TList(); // list holding all the graphs // Find all the segments making the contour Double_t r21, r20, r10; Int_t p0, p1, p2; Double_t x0, y0, z0; Double_t x1, y1, z1; Double_t x2, y2, z2; Int_t t[3],i,it,i0,i1,i2; // Allocate space to store the segments. They cannot be more than the // number of triangles. Double_t xs0c, ys0c, xs1c, ys1c; Double_t *xs0 = new Double_t[fNdt]; Double_t *ys0 = new Double_t[fNdt]; Double_t *xs1 = new Double_t[fNdt]; Double_t *ys1 = new Double_t[fNdt]; for (i=0;iz2) {z2=fZ[p1]; x2=fX[p1]; y2=fY[p1]; i2=1;} if (fZ[p2]<=z0) {z0=fZ[p2]; x0=fX[p2]; y0=fY[p2]; i0=2;} if (fZ[p2]>z2) {z2=fZ[p2]; x2=fX[p2]; y2=fY[p2]; i2=2;} if (i0==0 && i2==0) { Error("GetContourList", "wrong vertices ordering"); delete [] xs0; delete [] ys0; delete [] xs1; delete [] ys1; return 0; } else { i1 = 3-i2-i0; } x1 = fX[t[i1]-1]; y1 = fY[t[i1]-1]; z1 = fZ[t[i1]-1]; if (Hoption.Logz) { z0 = TMath::Log10(z0); z1 = TMath::Log10(z1); z2 = TMath::Log10(z2); } if(contour >= z0 && contour <=z2) { r20 = (contour-z0)/(z2-z0); xs0c = r20*(x2-x0)+x0; ys0c = r20*(y2-y0)+y0; if(contour >= z1 && contour <=z2) { r21 = (contour-z1)/(z2-z1); xs1c = r21*(x2-x1)+x1; ys1c = r21*(y2-y1)+y1; } else { r10 = (contour-z0)/(z1-z0); xs1c = r10*(x1-x0)+x0; ys1c = r10*(y1-y0)+y0; } // do not take the segments equal to a point if(xs0c != xs1c || ys0c != ys1c) { nbSeg++; xs0[nbSeg-1] = xs0c; ys0[nbSeg-1] = ys0c; xs1[nbSeg-1] = xs1c; ys1[nbSeg-1] = ys1c; } } } Bool_t *segUsed = new Bool_t[fNdt]; for(i=0; iSetPoint(npg,xs0[is],ys0[is]); npg++; graph->SetPoint(npg,xs1[is],ys1[is]); npg++; segUsed[is] = kTRUE; list->Add(graph); npg = 0; continue; } // Segment is is connected via 1 vertex only and can be considered // as the starting point of an opened contour. if (!s0 || !s1) { // Find all the segments connected to segment is graph = new TGraph(); if (s0) {xc = xs0[is]; yc = ys0[is]; xnc = xs1[is]; ync = ys1[is];} if (s1) {xc = xs1[is]; yc = ys1[is]; xnc = xs0[is]; ync = ys0[is];} graph->SetPoint(npg,xnc,ync); npg++; segUsed[is] = kTRUE; js = 0; L01: findNew = kFALSE; if (segUsed[js] && jsSetPoint(npg,xc,yc); npg++; js = 0; goto L01; } js++; if (jsAdd(graph); npg = 0; } } // Find the closed graphs. At this point all the remaining graphs // are closed. Any segment can be used to start the search. for (is=0; isSetPoint(npg,xc,yc); npg++; L02: findNew = kFALSE; if (segUsed[js] && jsSetPoint(npg,xc,yc); npg++; js = 0; goto L02; } js++; if (jsSetPoint(npg,xs0[is],ys0[is]); npg++; list->Add(graph); npg = 0; } delete [] xs0; delete [] ys0; delete [] xs1; delete [] ys1; delete [] segUsed; return list; } //______________________________________________________________________________ void TGraph2DPainter::Paint(Option_t *option) { // Paint a TGraphDelaunay according to the value of "option": // // "TRI" : The Delaunay triangles are drawn using filled area. // An hidden surface drawing technique is used. The surface is // painted with the current fill area color. The edges of each // triangles are painted with the current line color. // "TRIW" : The Delaunay triangles are drawn as wire frame // "TRI1" : The Delaunay triangles are painted with color levels. The edges // of each triangles are painted with the current line color. // "TRI2" : the Delaunay triangles are painted with color levels. // "P" : Draw a marker at each vertex // "P0" : Draw a circle at each vertex. Each circle background is white. // "PCOL" : Draw a marker at each vertex. The color of each marker is // defined according to its Z position. // "CONT" : Draw contours // "LINE" : Draw a 3D polyline TString opt = option; opt.ToLower(); Bool_t triangles = opt.Contains("tri") || opt.Contains("tri1") || opt.Contains("tri2"); if (opt.Contains("tri0")) triangles = kFALSE; Bool_t markers = opt.Contains("p") && !triangles; Bool_t contour = opt.Contains("cont"); Bool_t line = opt.Contains("line"); Bool_t err = opt.Contains("err"); fGraph2D->TAttLine::Modify(); fGraph2D->TAttFill::Modify(); fGraph2D->TAttMarker::Modify(); // Compute minimums and maximums TAxis *xaxis = gCurrentHist->GetXaxis(); Int_t first = xaxis->GetFirst(); fXmin = xaxis->GetBinLowEdge(first); if (Hoption.Logx && fXmin <= 0) fXmin = xaxis->GetBinUpEdge(xaxis->FindFixBin(0.01*xaxis->GetBinWidth(first))); fXmax = xaxis->GetBinUpEdge(xaxis->GetLast()); TAxis *yaxis = gCurrentHist->GetYaxis(); first = yaxis->GetFirst(); fYmin = yaxis->GetBinLowEdge(first); if (Hoption.Logy && fYmin <= 0) fYmin = yaxis->GetBinUpEdge(yaxis->FindFixBin(0.01*yaxis->GetBinWidth(first))); fYmax = yaxis->GetBinUpEdge(yaxis->GetLast()); fZmax = fGraph2D->GetZmax(); fZmin = fGraph2D->GetZmin(); if (Hoption.Logz && fZmin <= 0) fZmin = TMath::Min((Double_t)1, (Double_t)0.001*fGraph2D->GetZmax()); if (triangles) PaintTriangles(option); if (contour) PaintContour(option); if (line) PaintPolyLine(option); if (err) PaintErrors(option); if (markers) PaintPolyMarker(option); } //______________________________________________________________________________ void TGraph2DPainter::PaintContour(Option_t * /*option*/) { // Paints the 2D graph as a contour plot. Delaunay triangles are used // to compute the contours. // Initialize the levels on the Z axis Int_t ncolors = gStyle->GetNumberOfColors(); Int_t ndiv = gCurrentHist->GetContour(); if (ndiv == 0 ) { ndiv = gStyle->GetNumberContours(); gCurrentHist->SetContour(ndiv); } Int_t ndivz = TMath::Abs(ndiv); if (gCurrentHist->TestBit(TH1::kUserContour) == 0) gCurrentHist->SetContour(ndiv); Int_t theColor; TList *l; TGraph *g; TObject *obj; Double_t c; if (!fNdt) FindTriangles(); for (Int_t k=0; kGetContourLevelPad(k); l = GetContourList(c); TIter next(l); while ((obj = next())) { if(obj->InheritsFrom(TGraph::Class()) ) { g=(TGraph*)obj; g->SetLineWidth(fGraph2D->GetLineWidth()); g->SetLineStyle(fGraph2D->GetLineStyle()); theColor = Int_t((k+0.99)*Float_t(ncolors)/Float_t(ndivz)); g->SetLineColor(gStyle->GetColorPalette(theColor)); g->Paint("l"); } } } } //______________________________________________________________________________ void TGraph2DPainter::PaintErrors(Option_t * /* option */) { // Paints the 2D graph as error bars Double_t temp1[3],temp2[3]; TView *view = gPad->GetView(); if (!view) { Error("PaintErrors", "No TView in current pad"); return; } Int_t it; Double_t *xm = new Double_t[2]; Double_t *ym = new Double_t[2]; fGraph2D->SetLineStyle(fGraph2D->GetLineStyle()); fGraph2D->SetLineWidth(fGraph2D->GetLineWidth()); fGraph2D->SetLineColor(fGraph2D->GetLineColor()); fGraph2D->TAttLine::Modify(); for (it=0; it fXmax) continue; if(fY[it] < fYmin || fY[it] > fYmax) continue; if (fEX) { temp1[0] = fX[it]-fEX[it]; temp1[1] = fY[it]; temp1[2] = fZ[it]; temp1[0] = TMath::Max(temp1[0],fXmin); temp1[1] = TMath::Max(temp1[1],fYmin); temp1[2] = TMath::Max(temp1[2],fZmin); temp1[2] = TMath::Min(temp1[2],fZmax); if (Hoption.Logx) temp1[0] = TMath::Log10(temp1[0]); if (Hoption.Logy) temp1[1] = TMath::Log10(temp1[1]); if (Hoption.Logz) temp1[2] = TMath::Log10(temp1[2]); view->WCtoNDC(temp1, &temp2[0]); xm[0] = temp2[0]; ym[0] = temp2[1]; temp1[0] = fX[it]+fEX[it]; temp1[0] = TMath::Max(temp1[0],fXmin); if (Hoption.Logx) temp1[0] = TMath::Log10(temp1[0]); view->WCtoNDC(temp1, &temp2[0]); xm[1] = temp2[0]; ym[1] = temp2[1]; gPad->PaintPolyLine(2,xm,ym); } if (fEY) { temp1[0] = fX[it]; temp1[1] = fY[it]-fEY[it]; temp1[2] = fZ[it]; temp1[0] = TMath::Max(temp1[0],fXmin); temp1[1] = TMath::Max(temp1[1],fYmin); temp1[2] = TMath::Max(temp1[2],fZmin); temp1[2] = TMath::Min(temp1[2],fZmax); if (Hoption.Logx) temp1[0] = TMath::Log10(temp1[0]); if (Hoption.Logy) temp1[1] = TMath::Log10(temp1[1]); if (Hoption.Logz) temp1[2] = TMath::Log10(temp1[2]); view->WCtoNDC(temp1, &temp2[0]); xm[0] = temp2[0]; ym[0] = temp2[1]; temp1[1] = fY[it]+fEY[it]; temp1[1] = TMath::Max(temp1[1],fYmin); if (Hoption.Logy) temp1[1] = TMath::Log10(temp1[1]); view->WCtoNDC(temp1, &temp2[0]); xm[1] = temp2[0]; ym[1] = temp2[1]; gPad->PaintPolyLine(2,xm,ym); } if (fEZ) { temp1[0] = fX[it]; temp1[1] = fY[it]; temp1[2] = fZ[it]-fEZ[it]; temp1[0] = TMath::Max(temp1[0],fXmin); temp1[1] = TMath::Max(temp1[1],fYmin); temp1[2] = TMath::Max(temp1[2],fZmin); temp1[2] = TMath::Min(temp1[2],fZmax); if (Hoption.Logx) temp1[0] = TMath::Log10(temp1[0]); if (Hoption.Logy) temp1[1] = TMath::Log10(temp1[1]); if (Hoption.Logz) temp1[2] = TMath::Log10(temp1[2]); view->WCtoNDC(temp1, &temp2[0]); xm[0] = temp2[0]; ym[0] = temp2[1]; temp1[2] = fZ[it]+fEZ[it]; temp1[2] = TMath::Max(temp1[2],fZmin); temp1[2] = TMath::Min(temp1[2],fZmax); if (Hoption.Logz) temp1[2] = TMath::Log10(temp1[2]); view->WCtoNDC(temp1, &temp2[0]); xm[1] = temp2[0]; ym[1] = temp2[1]; gPad->PaintPolyLine(2,xm,ym); } } delete [] xm; delete [] ym; } //______________________________________________________________________________ void TGraph2DPainter::PaintLevels(Int_t *t,Double_t *x, Double_t *y, Int_t nblev, Double_t *glev) { // Paints one triangle. // nblev = 0 : paint the color levels // nblev != 0 : paint the grid Int_t i, fillColor, ncolors, theColor0, theColor2; Int_t p0=t[0]-1; Int_t p1=t[1]-1; Int_t p2=t[2]-1; Double_t xl[2],yl[2]; Double_t zl, r21, r20, r10; Double_t x0 = x[0] , x2 = x[0]; Double_t y0 = y[0] , y2 = y[0]; Double_t z0 = fZ[p0], z2 = fZ[p0]; Double_t zmin = fGraph2D->GetMinimum(); Double_t zmax = fGraph2D->GetMaximum(); if (zmin==-1111 && zmax==-1111) { zmin = fZmin; zmax = fZmax; } // Order along Z axis the points (xi,yi,zi) where "i" belongs to {0,1,2} // After this z0 < z1 < z2 Int_t i0=0, i1=0, i2=0; if (fZ[p1]<=z0) {z0=fZ[p1]; x0=x[1]; y0=y[1]; i0=1;} if (fZ[p1]>z2) {z2=fZ[p1]; x2=x[1]; y2=y[1]; i2=1;} if (fZ[p2]<=z0) {z0=fZ[p2]; x0=x[2]; y0=y[2]; i0=2;} if (fZ[p2]>z2) {z2=fZ[p2]; x2=x[2]; y2=y[2]; i2=2;} i1 = 3-i2-i0; Double_t x1 = x[i1]; Double_t y1 = y[i1]; Double_t z1 = fZ[t[i1]-1]; if (z0>zmax) z0 = zmax; if (z2>zmax) z2 = zmax; if (z0zmax) z1 = zmax; if (z1GetNumberOfColors(); theColor0 = (Int_t)( ((z0-zmin)/(zmax-zmin))*(ncolors-1) ); theColor2 = (Int_t)( ((z2-zmin)/(zmax-zmin))*(ncolors-1) ); // The stripes drawn to fill the triangles may have up to 5 points Double_t xp[5], yp[5]; // rl = Ratio between z0 and z2 (long) // rs = Ratio between z0 and z1 or z1 and z2 (short) Double_t rl,rs; // ci = Color of the stripe number i // npf = number of point needed to draw the current stripe Int_t ci,npf; fillColor = fGraph2D->GetFillColor(); // If the z0's color and z2's colors are the same, the whole triangle // can be painted in one go. if(theColor0 == theColor2) { fGraph2D->SetFillColor(gStyle->GetColorPalette(theColor0)); fGraph2D->TAttFill::Modify(); gPad->PaintFillArea(3,x,y); // The triangle must be painted with several colors } else { for(ci=theColor0; ci<=theColor2; ci++) { fGraph2D->SetFillColor(gStyle->GetColorPalette(ci)); fGraph2D->TAttFill::Modify(); if (ci==theColor0) { zi = (((ci+1)*(zmax-zmin))/(ncolors-1))+zmin; xp[0] = x0; yp[0] = y0; rl = (zi-z0)/(z2-z0); xp[1] = rl*(x2-x0)+x0; yp[1] = rl*(y2-y0)+y0; if (zi>=z1 || z0==z1) { rs = (zi-z1)/(z2-z1); xp[2] = rs*(x2-x1)+x1; yp[2] = rs*(y2-y1)+y1; xp[3] = x1; yp[3] = y1; npf = 4; } else { rs = (zi-z0)/(z1-z0); xp[2] = rs*(x1-x0)+x0; yp[2] = rs*(y1-y0)+y0; npf = 3; } } else if (ci==theColor2) { xp[0] = xp[1]; yp[0] = yp[1]; xp[1] = x2; yp[1] = y2; if (zi=z1 && zip<=z1) { xp[3] = x1; yp[3] = y1; xp[4] = xp[2]; yp[4] = yp[2]; npf = 5; } else { xp[3] = xp[2]; yp[3] = yp[2]; npf = 4; } if (ziPaintFillArea(npf,xp,yp); } } fGraph2D->SetFillColor(fillColor); fGraph2D->TAttFill::Modify(); } else { // Paint the grid levels fGraph2D->SetLineStyle(3); fGraph2D->TAttLine::Modify(); for(i=0; i= z0 && zl <=z2) { r21=(zl-z1)/(z2-z1); r20=(zl-z0)/(z2-z0); r10=(zl-z0)/(z1-z0); xl[0]=r20*(x2-x0)+x0; yl[0]=r20*(y2-y0)+y0; if(zl >= z1 && zl <=z2) { xl[1]=r21*(x2-x1)+x1; yl[1]=r21*(y2-y1)+y1; } else { xl[1]=r10*(x1-x0)+x0; yl[1]=r10*(y1-y0)+y0; } gPad->PaintPolyLine(2,xl,yl); } } fGraph2D->SetLineStyle(1); fGraph2D->TAttLine::Modify(); } } //______________________________________________________________________________ void TGraph2DPainter::PaintPolyMarker(Option_t *option) { // Paints the 2D graph as PaintPolyMarker Double_t temp1[3],temp2[3]; TView *view = gPad->GetView(); if (!view) { Error("PaintPolyMarker", "No TView in current pad"); return; } TString opt = option; opt.ToLower(); Bool_t markers0 = opt.Contains("p0"); Bool_t colors = opt.Contains("pcol"); Int_t ncolors = gStyle->GetNumberOfColors(); Int_t it, theColor; // Initialize the levels on the Z axis if (colors) { Int_t ndiv = gCurrentHist->GetContour(); if (ndiv == 0 ) { ndiv = gStyle->GetNumberContours(); gCurrentHist->SetContour(ndiv); } if (gCurrentHist->TestBit(TH1::kUserContour) == 0) gCurrentHist->SetContour(ndiv); } Double_t *xm = new Double_t[fNpoints]; Double_t *ym = new Double_t[fNpoints]; Double_t hzmin = gCurrentHist->GetMinimum(); Double_t hzmax = gCurrentHist->GetMaximum(); Int_t npd = 0; for (it=0; it fXmax) continue; if(fY[it] < fYmin || fY[it] > fYmax) continue; if(fZ[it] < hzmin || fZ[it] > hzmax) continue; npd++; temp1[0] = fX[it]; temp1[1] = fY[it]; temp1[2] = fZ[it]; temp1[0] = TMath::Max(temp1[0],fXmin); temp1[1] = TMath::Max(temp1[1],fYmin); temp1[2] = TMath::Max(temp1[2],hzmin); temp1[2] = TMath::Min(temp1[2],hzmax); if (Hoption.Logx) temp1[0] = TMath::Log10(temp1[0]); if (Hoption.Logy) temp1[1] = TMath::Log10(temp1[1]); if (Hoption.Logz) temp1[2] = TMath::Log10(temp1[2]); view->WCtoNDC(temp1, &temp2[0]); xm[it] = temp2[0]; ym[it] = temp2[1]; } if (markers0) { PaintPolyMarker0(npd,xm,ym); } else if (colors) { for (it=0; itSetMarkerColor(gStyle->GetColorPalette(theColor)); fGraph2D->TAttMarker::Modify(); gPad->PaintPolyMarker(1,&xm[it],&ym[it]); } } else { fGraph2D->SetMarkerStyle(fGraph2D->GetMarkerStyle()); fGraph2D->SetMarkerSize(fGraph2D->GetMarkerSize()); fGraph2D->SetMarkerColor(fGraph2D->GetMarkerColor()); fGraph2D->TAttMarker::Modify(); gPad->PaintPolyMarker(npd,xm,ym); } delete [] xm; delete [] ym; } //______________________________________________________________________________ void TGraph2DPainter::PaintPolyLine(Option_t * /* option */) { // Paints the 2D graph as PaintPolyLine Double_t temp1[3],temp2[3]; TView *view = gPad->GetView(); if (!view) { Error("PaintPolyLine", "No TView in current pad"); return; } Int_t it; Double_t *xm = new Double_t[fNpoints]; Double_t *ym = new Double_t[fNpoints]; Int_t npd = 0; for (it=0; it fXmax) continue; if(fY[it] < fYmin || fY[it] > fYmax) continue; npd++; temp1[0] = fX[it]; temp1[1] = fY[it]; temp1[2] = fZ[it]; temp1[0] = TMath::Max(temp1[0],fXmin); temp1[1] = TMath::Max(temp1[1],fYmin); temp1[2] = TMath::Max(temp1[2],fZmin); temp1[2] = TMath::Min(temp1[2],fZmax); if (Hoption.Logx) temp1[0] = TMath::Log10(temp1[0]); if (Hoption.Logy) temp1[1] = TMath::Log10(temp1[1]); if (Hoption.Logz) temp1[2] = TMath::Log10(temp1[2]); view->WCtoNDC(temp1, &temp2[0]); xm[it] = temp2[0]; ym[it] = temp2[1]; } fGraph2D->SetLineStyle(fGraph2D->GetLineStyle()); fGraph2D->SetLineWidth(fGraph2D->GetLineWidth()); fGraph2D->SetLineColor(fGraph2D->GetLineColor()); fGraph2D->TAttLine::Modify(); gPad->PaintPolyLine(npd,xm,ym); delete [] xm; delete [] ym; } //______________________________________________________________________________ void TGraph2DPainter::PaintPolyMarker0(Int_t n, Double_t *x, Double_t *y) { // Paints a circle at each vertex. Each circle background is white. fGraph2D->SetMarkerSize(fGraph2D->GetMarkerSize()); Int_t mc = fGraph2D->GetMarkerColor(); for (Int_t i=0; iSetMarkerStyle(20); fGraph2D->SetMarkerColor(0); fGraph2D->TAttMarker::Modify(); gPad->PaintPolyMarker(1,&x[i],&y[i]); fGraph2D->SetMarkerStyle(24); fGraph2D->SetMarkerColor(mc); fGraph2D->TAttMarker::Modify(); gPad->PaintPolyMarker(1,&x[i],&y[i]); } } //______________________________________________________________________________ void TGraph2DPainter::PaintTriangles(Option_t *option) { // Paints the 2D graph as triangles Double_t x[4], y[4], temp1[3],temp2[3]; Int_t it,t[3]; Int_t *order = 0; Double_t *dist = 0; TView *view = gPad->GetView(); if (!view) { Error("PaintTriangles", "No TView in current pad"); return; } TString opt = option; opt.ToLower(); Bool_t tri1 = opt.Contains("tri1"); Bool_t tri2 = opt.Contains("tri2"); Bool_t markers = opt.Contains("p"); Bool_t markers0 = opt.Contains("p0"); Bool_t wire = opt.Contains("w"); // Define the grid levels drawn on the triangles. // The grid levels are aligned on the Z axis' main tick marks. Int_t nblev=0; Double_t *glev=0; if (!tri1 && !tri2 && !wire) { Int_t ndivz = gCurrentHist->GetZaxis()->GetNdivisions()%100; Int_t nbins; Double_t binLow = 0, binHigh = 0, binWidth = 0; // Find the main tick marks positions. Double_t *r0 = view->GetRmin(); Double_t *r1 = view->GetRmax(); if (!r0 || !r1) return; if (ndivz > 0) { THLimitsFinder::Optimize(r0[2], r1[2], ndivz, binLow, binHigh, nbins, binWidth, " "); } else { nbins = TMath::Abs(ndivz); binLow = r0[2]; binHigh = r1[2]; binWidth = (binHigh-binLow)/nbins; } // Define the grid levels nblev = nbins+1; glev = new Double_t[nblev]; for (Int_t i = 0; i < nblev; ++i) glev[i] = binLow+i*binWidth; } // Initialize the levels on the Z axis if (tri1 || tri2) { Int_t ndiv = gCurrentHist->GetContour(); if (ndiv == 0 ) { ndiv = gStyle->GetNumberContours(); gCurrentHist->SetContour(ndiv); } if (gCurrentHist->TestBit(TH1::kUserContour) == 0) gCurrentHist->SetContour(ndiv); } // For each triangle, compute the distance between the triangle centre // and the back planes. Then these distances are sorted in order to draw // the triangles from back to front. if (!fNdt) FindTriangles(); Double_t cp = TMath::Cos(view->GetLongitude()*TMath::Pi()/180.); Double_t sp = TMath::Sin(view->GetLongitude()*TMath::Pi()/180.); order = new Int_t[fNdt]; dist = new Double_t[fNdt]; Double_t xd,yd; Int_t p, n, m; Bool_t o = kFALSE; for (it=0; it= 0) && (sp >= 0.)) { dist[it] = -(fXNmax-xd+fYNmax-yd); } else if ((cp <= 0) && (sp >= 0.)) { dist[it] = -(fXNmax-xd+yd-fYNmin); o = kTRUE; } else if ((cp <= 0) && (sp <= 0.)) { dist[it] = -(xd-fXNmin+yd-fYNmin); } else { dist[it] = -(xd-fXNmin+fYNmax-yd); o = kTRUE; } } TMath::Sort(fNdt, dist, order, o); // Draw the triangles and markers if requested fGraph2D->SetFillColor(fGraph2D->GetFillColor()); Int_t fs = fGraph2D->GetFillStyle(); fGraph2D->SetFillStyle(1001); fGraph2D->TAttFill::Modify(); fGraph2D->SetLineColor(fGraph2D->GetLineColor()); fGraph2D->TAttLine::Modify(); int lst = fGraph2D->GetLineStyle(); for (it=0; it fXmax) goto endloop; if(fY[t[k]-1] < fYmin || fY[t[k]-1] > fYmax) goto endloop; temp1[0] = fX[t[k]-1]; temp1[1] = fY[t[k]-1]; temp1[2] = fZ[t[k]-1]; temp1[0] = TMath::Max(temp1[0],fXmin); temp1[1] = TMath::Max(temp1[1],fYmin); temp1[2] = TMath::Max(temp1[2],fZmin); temp1[2] = TMath::Min(temp1[2],fZmax); if (Hoption.Logx) temp1[0] = TMath::Log10(temp1[0]); if (Hoption.Logy) temp1[1] = TMath::Log10(temp1[1]); if (Hoption.Logz) temp1[2] = TMath::Log10(temp1[2]); view->WCtoNDC(temp1, &temp2[0]); x[k] = temp2[0]; y[k] = temp2[1]; } x[3] = x[0]; y[3] = y[0]; if (tri1 || tri2) PaintLevels(t,x,y); if (!tri1 && !tri2 && !wire) { gPad->PaintFillArea(3,x,y); PaintLevels(t,x,y,nblev,glev); } if (!tri2) gPad->PaintPolyLine(4,x,y); if (markers) { if (markers0) { PaintPolyMarker0(3,x,y); } else { fGraph2D->SetMarkerStyle(fGraph2D->GetMarkerStyle()); fGraph2D->SetMarkerSize(fGraph2D->GetMarkerSize()); fGraph2D->SetMarkerColor(fGraph2D->GetMarkerColor()); fGraph2D->TAttMarker::Modify(); gPad->PaintPolyMarker(3,x,y); } } endloop: continue; } fGraph2D->SetFillStyle(fs); fGraph2D->SetLineStyle(lst); fGraph2D->TAttLine::Modify(); fGraph2D->TAttFill::Modify(); delete [] order; delete [] dist; if (glev) delete [] glev; }