Logo ROOT   6.10/09
Reference Guide
TGraph2DPainter.cxx
Go to the documentation of this file.
1 // @(#)root/histpainter:$Id: TGraph2DPainter.cxx,v 1.00
2 // Author: Olivier Couet
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "TROOT.h"
13 #include "TGraph2DPainter.h"
14 #include "TMath.h"
15 #include "TList.h"
16 #include "TGraph.h"
17 #include "TGraph2D.h"
18 #include "TGraphDelaunay.h"
19 #include "TGraphDelaunay2D.h"
20 #include "TPolyLine.h"
21 #include "TPolyMarker.h"
22 #include "TVirtualPad.h"
23 #include "TView.h"
24 #include "THLimitsFinder.h"
25 #include "TStyle.h"
26 #include "Hoption.h"
27 #include "TH1.h"
28 
31 
33 
34 
35 ////////////////////////////////////////////////////////////////////////////////
36 /*! \class TGraph2DPainter
37  \ingroup Histpainter
38  \brief The TGraphDelaunay painting class.
39 
40 TGraph2DPainter paints a TGraphDelaunay using triangles or clouds of points.
41 
42 */
43 
44 
45 ////////////////////////////////////////////////////////////////////////////////
46 /// TGraph2DPainter default constructor
47 
49 {
50  fX = 0;
51  fY = 0;
52  fZ = 0;
53  fEX = 0;
54  fEY = 0;
55  fEZ = 0;
56  fXN = 0;
57  fYN = 0;
58  fPTried = 0;
59  fNTried = 0;
60  fMTried = 0;
61  fGraph2D = 0;
62  fDelaunay = 0;
63  fDelaunay2D = 0;
64  fXmin = 0.;
65  fXmax = 0.;
66  fYmin = 0.;
67  fYmax = 0.;
68  fZmin = 0.;
69  fZmax = 0.;
70  fXNmin = 0;
71  fXNmax = 0;
72  fYNmin = 0;
73  fYNmax = 0;
74  fNdt = 0;
75  fNpoints = 0;
76 }
77 
78 
79 ////////////////////////////////////////////////////////////////////////////////
80 /// TGraph2DPainter constructor using the old Delaunay algorithm
81 
83 {
84  fDelaunay = gd;
85  fDelaunay2D = 0;
87  fNpoints = fGraph2D->GetN();
88  fX = fGraph2D->GetX();
89  fY = fGraph2D->GetY();
90  fZ = fGraph2D->GetZ();
91  fEX = fGraph2D->GetEX();
92  fEY = fGraph2D->GetEY();
93  fEZ = fGraph2D->GetEZ();
94  fNdt = 0;
95  fXN = 0;
96  fYN = 0;
97  fXNmin = 0;
98  fXNmax = 0;
99  fYNmin = 0;
100  fYNmax = 0;
101  fPTried = 0;
102  fNTried = 0;
103  fMTried = 0;
104  fXmin = 0.;
105  fXmax = 0.;
106  fYmin = 0.;
107  fYmax = 0.;
108  fZmin = 0.;
109  fZmax = 0.;
110 }
111 
112 ////////////////////////////////////////////////////////////////////////////////
113 /// TGraph2DPainter constructor using the new Delaunay algorithm
114 
116 {
117  fDelaunay = 0;
118  fDelaunay2D = gd;
120  fNpoints = fGraph2D->GetN();
121  fX = fGraph2D->GetX();
122  fY = fGraph2D->GetY();
123  fZ = fGraph2D->GetZ();
124  fEX = fGraph2D->GetEX();
125  fEY = fGraph2D->GetEY();
126  fEZ = fGraph2D->GetEZ();
127  fNdt = 0;
128  fXN = 0;
129  fYN = 0;
130  fXNmin = 0;
131  fXNmax = 0;
132  fYNmin = 0;
133  fYNmax = 0;
134  fPTried = 0;
135  fNTried = 0;
136  fMTried = 0;
137  fXmin = 0.;
138  fXmax = 0.;
139  fYmin = 0.;
140  fYmax = 0.;
141  fZmin = 0.;
142  fZmax = 0.;
143 }
144 
145 
146 ////////////////////////////////////////////////////////////////////////////////
147 /// TGraph2DPainter destructor.
148 
150 {
151 }
152 
153 
154 ////////////////////////////////////////////////////////////////////////////////
155 /// Find triangles in fDelaunay and initialise the TGraph2DPainter values
156 /// needed to paint triangles or find contours.
157 
159 {
160  if (fDelaunay) {
162  fNdt = fDelaunay->GetNdt();
163  fXN = fDelaunay->GetXN();
164  fYN = fDelaunay->GetYN();
172  }
173  else if (fDelaunay2D) {
175  fNdt = fDelaunay2D->GetNdt();
180  }
181 }
182 
183 
184 ////////////////////////////////////////////////////////////////////////////////
185 /// Returns the X and Y graphs building a contour. A contour level may
186 /// consist in several parts not connected to each other. This function
187 /// finds them and returns them in a graphs' list.
188 
190 {
191  // Exit if the contour is outisde the Z range.
192  Double_t zmin = gCurrentHist->GetMinimum();
193  Double_t zmax = gCurrentHist->GetMaximum();
194  if (Hoption.Logz) {
195  if (zmin > 0) {
196  zmin = TMath::Log10(zmin);
197  zmax = TMath::Log10(zmax);
198  } else {
199  return 0;
200  }
201  }
202  if(contour<zmin || contour>zmax) {
203  Error("GetContourList", "Contour level (%g) outside the Z scope [%g,%g]",
204  contour,zmin,zmax);
205  return 0;
206  }
207 
208  if (!fNdt) FindTriangles();
209 
210  TGraph *graph = 0; // current graph
211  Int_t npg = 0; // number of points in the current graph
212  TList *list = new TList(); // list holding all the graphs
213 
214  // Find all the segments making the contour
215 
216  Double_t r21, r20, r10;
217  Int_t p0, p1, p2;
218  Double_t x0, y0, z0;
219  Double_t x1, y1, z1;
220  Double_t x2, y2, z2;
221  Int_t t[3],i,it,i0,i1,i2;
222 
223  // Allocate space to store the segments. They cannot be more than the
224  // number of triangles.
225  Double_t xs0c, ys0c, xs1c, ys1c;
226  Double_t *xs0 = new Double_t[fNdt];
227  Double_t *ys0 = new Double_t[fNdt];
228  Double_t *xs1 = new Double_t[fNdt];
229  Double_t *ys1 = new Double_t[fNdt];
230  for (i=0;i<fNdt;i++) {
231  xs0[i] = 0.;
232  ys0[i] = 0.;
233  xs1[i] = 0.;
234  ys1[i] = 0.;
235  }
236  Int_t nbSeg = 0;
237 
238  // Loop over all the triangles in order to find all the line segments
239  // making the contour.
240 
241  // old implementation
242  if (fDelaunay) {
243  for(it=0; it<fNdt; it++) {
244  t[0] = fPTried[it];
245  t[1] = fNTried[it];
246  t[2] = fMTried[it];
247  p0 = t[0]-1;
248  p1 = t[1]-1;
249  p2 = t[2]-1;
250  x0 = fX[p0]; x2 = fX[p0];
251  y0 = fY[p0]; y2 = fY[p0];
252  z0 = fZ[p0]; z2 = fZ[p0];
253 
254  // Order along Z axis the points (xi,yi,zi) where "i" belongs to {0,1,2}
255  // After this z0 < z1 < z2
256  i0=0, i1=0, i2=0;
257  if (fZ[p1]<=z0) {z0=fZ[p1]; x0=fX[p1]; y0=fY[p1]; i0=1;}
258  if (fZ[p1]>z2) {z2=fZ[p1]; x2=fX[p1]; y2=fY[p1]; i2=1;}
259  if (fZ[p2]<=z0) {z0=fZ[p2]; x0=fX[p2]; y0=fY[p2]; i0=2;}
260  if (fZ[p2]>z2) {z2=fZ[p2]; x2=fX[p2]; y2=fY[p2]; i2=2;}
261  if (i0==0 && i2==0) {
262  Error("GetContourList", "wrong vertices ordering");
263  delete [] xs0;
264  delete [] ys0;
265  delete [] xs1;
266  delete [] ys1;
267  return 0;
268  } else {
269  i1 = 3-i2-i0;
270  }
271  x1 = fX[t[i1]-1];
272  y1 = fY[t[i1]-1];
273  z1 = fZ[t[i1]-1];
274 
275  if (Hoption.Logz) {
276  z0 = TMath::Log10(z0);
277  z1 = TMath::Log10(z1);
278  z2 = TMath::Log10(z2);
279  }
280 
281  if(contour >= z0 && contour <=z2) {
282  r20 = (contour-z0)/(z2-z0);
283  xs0c = r20*(x2-x0)+x0;
284  ys0c = r20*(y2-y0)+y0;
285  if(contour >= z1 && contour <=z2) {
286  r21 = (contour-z1)/(z2-z1);
287  xs1c = r21*(x2-x1)+x1;
288  ys1c = r21*(y2-y1)+y1;
289  } else {
290  r10 = (contour-z0)/(z1-z0);
291  xs1c = r10*(x1-x0)+x0;
292  ys1c = r10*(y1-y0)+y0;
293  }
294  // do not take the segments equal to a point
295  if(xs0c != xs1c || ys0c != ys1c) {
296  nbSeg++;
297  xs0[nbSeg-1] = xs0c;
298  ys0[nbSeg-1] = ys0c;
299  xs1[nbSeg-1] = xs1c;
300  ys1[nbSeg-1] = ys1c;
301  }
302  }
303  }
304  }
305  else if (fDelaunay2D) {
306 
307  Int_t p[3];
308  for(const auto & face : *fDelaunay2D) {
309  p[0] = face.idx[0];
310  p[1] = face.idx[1];
311  p[2] = face.idx[2];
312  x0 = fX[p[0]]; x2 = fX[p[0]];
313  y0 = fY[p[0]]; y2 = fY[p[0]];
314  z0 = fZ[p[0]]; z2 = fZ[p[0]];
315 
316  // Order along Z axis the points (xi,yi,zi) where "i" belongs to {0,1,2}
317  // After this z0 < z1 < z2
318  i0=0, i1=0, i2=0;
319  if (fZ[p[1]]<=z0) {z0=fZ[p[1]]; x0=fX[p[1]]; y0=fY[p[1]]; i0=1;}
320  if (fZ[p[1]]>z2) {z2=fZ[p[1]]; x2=fX[p[1]]; y2=fY[p[1]]; i2=1;}
321  if (fZ[p[2]]<=z0) {z0=fZ[p[2]]; x0=fX[p[2]]; y0=fY[p[2]]; i0=2;}
322  if (fZ[p[2]]>z2) {z2=fZ[p[2]]; x2=fX[p[2]]; y2=fY[p[2]]; i2=2;}
323  if (i0==0 && i2==0) {
324  Error("GetContourList", "wrong vertices ordering");
325  delete [] xs0;
326  delete [] ys0;
327  delete [] xs1;
328  delete [] ys1;
329  return 0;
330  } else {
331  i1 = 3-i2-i0;
332  }
333  x1 = fX[p[i1]];
334  y1 = fY[p[i1]];
335  z1 = fZ[p[i1]];
336 
337  if (Hoption.Logz) {
338  z0 = TMath::Log10(z0);
339  z1 = TMath::Log10(z1);
340  z2 = TMath::Log10(z2);
341  }
342 
343  if(contour >= z0 && contour <=z2) {
344  r20 = (contour-z0)/(z2-z0);
345  xs0c = r20*(x2-x0)+x0;
346  ys0c = r20*(y2-y0)+y0;
347  if(contour >= z1 && contour <=z2) {
348  r21 = (contour-z1)/(z2-z1);
349  xs1c = r21*(x2-x1)+x1;
350  ys1c = r21*(y2-y1)+y1;
351  } else {
352  r10 = (contour-z0)/(z1-z0);
353  xs1c = r10*(x1-x0)+x0;
354  ys1c = r10*(y1-y0)+y0;
355  }
356  // do not take the segments equal to a point
357  if(xs0c != xs1c || ys0c != ys1c) {
358  nbSeg++;
359  xs0[nbSeg-1] = xs0c;
360  ys0[nbSeg-1] = ys0c;
361  xs1[nbSeg-1] = xs1c;
362  ys1[nbSeg-1] = ys1c;
363  }
364  }
365  }
366  }
367 
368  Int_t *segUsed = new Int_t[fNdt];
369  for(i=0; i<fNdt; i++) segUsed[i]=kFALSE;
370 
371  // Find all the graphs making the contour. There is two kind of graphs,
372  // either they are "opened" or they are "closed"
373 
374  // Find the opened graphs
375  Double_t xc=0, yc=0, xnc=0, ync=0;
376  Bool_t findNew;
377  Bool_t s0, s1;
378  Int_t is, js;
379  for (is=0; is<nbSeg; is++) {
380  if (segUsed[is]) continue;
381  s0 = s1 = kFALSE;
382 
383  // Find to which segment is is connected. It can be connected
384  // via 0, 1 or 2 vertices.
385  for (js=0; js<nbSeg; js++) {
386  if (is==js) continue;
387  if (xs0[is]==xs0[js] && ys0[is]==ys0[js]) s0 = kTRUE;
388  if (xs0[is]==xs1[js] && ys0[is]==ys1[js]) s0 = kTRUE;
389  if (xs1[is]==xs0[js] && ys1[is]==ys0[js]) s1 = kTRUE;
390  if (xs1[is]==xs1[js] && ys1[is]==ys1[js]) s1 = kTRUE;
391  }
392 
393  // Segment is is alone, not connected. It is stored in the
394  // list and the next segment is examined.
395  if (!s0 && !s1) {
396  graph = new TGraph();
397  graph->SetPoint(npg,xs0[is],ys0[is]); npg++;
398  graph->SetPoint(npg,xs1[is],ys1[is]); npg++;
399  segUsed[is] = kTRUE;
400  list->Add(graph); npg = 0;
401  continue;
402  }
403 
404  // Segment is is connected via 1 vertex only and can be considered
405  // as the starting point of an opened contour.
406  if (!s0 || !s1) {
407  // Find all the segments connected to segment is
408  graph = new TGraph();
409  if (s0) {xc = xs0[is]; yc = ys0[is]; xnc = xs1[is]; ync = ys1[is];}
410  if (s1) {xc = xs1[is]; yc = ys1[is]; xnc = xs0[is]; ync = ys0[is];}
411  graph->SetPoint(npg,xnc,ync); npg++;
412  segUsed[is] = kTRUE;
413  js = 0;
414 L01:
415  findNew = kFALSE;
416  if (segUsed[js] && js<nbSeg) {
417  js++;
418  goto L01;
419  } else if (xc==xs0[js] && yc==ys0[js]) {
420  xc = xs1[js];
421  yc = ys1[js];
422  findNew = kTRUE;
423  } else if (xc==xs1[js] && yc==ys1[js]) {
424  xc = xs0[js];
425  yc = ys0[js];
426  findNew = kTRUE;
427  }
428  if (findNew) {
429  segUsed[js] = kTRUE;
430  graph->SetPoint(npg,xc,yc); npg++;
431  js = 0;
432  goto L01;
433  }
434  js++;
435  if (js<nbSeg) goto L01;
436  list->Add(graph); npg = 0;
437  }
438  }
439 
440 
441  // Find the closed graphs. At this point all the remaining graphs
442  // are closed. Any segment can be used to start the search.
443  for (is=0; is<nbSeg; is++) {
444  if (segUsed[is]) continue;
445 
446  // Find all the segments connected to segment is
447  graph = new TGraph();
448  segUsed[is] = kTRUE;
449  xc = xs0[is];
450  yc = ys0[is];
451  js = 0;
452  graph->SetPoint(npg,xc,yc); npg++;
453 L02:
454  findNew = kFALSE;
455  if (segUsed[js] && js<nbSeg) {
456  js++;
457  goto L02;
458  } else if (xc==xs0[js] && yc==ys0[js]) {
459  xc = xs1[js];
460  yc = ys1[js];
461  findNew = kTRUE;
462  } else if (xc==xs1[js] && yc==ys1[js]) {
463  xc = xs0[js];
464  yc = ys0[js];
465  findNew = kTRUE;
466  }
467  if (findNew) {
468  segUsed[js] = kTRUE;
469  graph->SetPoint(npg,xc,yc); npg++;
470  js = 0;
471  goto L02;
472  }
473  js++;
474  if (js<nbSeg) goto L02;
475  // Close the contour
476  graph->SetPoint(npg,xs0[is],ys0[is]); npg++;
477  list->Add(graph); npg = 0;
478  }
479 
480  delete [] xs0;
481  delete [] ys0;
482  delete [] xs1;
483  delete [] ys1;
484  delete [] segUsed;
485  return list;
486 }
487 
488 
489 ////////////////////////////////////////////////////////////////////////////////
490 /// Paint a TGraphDelaunay according to the value of "option":
491 ///
492 /// | Option | Description |
493 /// |----------|---------------------------------------------------------------|
494 /// | "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. |
495 /// | "TRIW" | The Delaunay triangles are drawn as wire frame. |
496 /// | "TRI1" | The Delaunay triangles are painted with color levels. The edges of each triangles are painted with the current line color. |
497 /// | "TRI2" | the Delaunay triangles are painted with color levels. |
498 /// | "P" | Draw a marker at each vertex. |
499 /// | "P0" | Draw a circle at each vertex. Each circle background is white. |
500 /// | "PCOL" | Draw a marker at each vertex. The color of each marker is defined according to its Z position. |
501 /// | "CONT" | Draw contours. |
502 /// | "LINE" | Draw a 3D polyline. |
503 
505 {
506  TString opt = option;
507  opt.ToLower();
508  Bool_t triangles = opt.Contains("tri") ||
509  opt.Contains("tri1") ||
510  opt.Contains("tri2");
511  if (opt.Contains("tri0")) triangles = kFALSE;
512 
513  Bool_t markers = opt.Contains("p") && !triangles;
514  Bool_t contour = opt.Contains("cont");
515  Bool_t line = opt.Contains("line");
516  Bool_t err = opt.Contains("err");
517 
518  fGraph2D->TAttLine::Modify();
519  fGraph2D->TAttFill::Modify();
520  fGraph2D->TAttMarker::Modify();
521 
522  // Compute minimums and maximums
523  TAxis *xaxis = gCurrentHist->GetXaxis();
524  Int_t first = xaxis->GetFirst();
525  fXmin = xaxis->GetBinLowEdge(first);
526  if (Hoption.Logx && fXmin <= 0) fXmin = xaxis->GetBinUpEdge(xaxis->FindFixBin(0.01*xaxis->GetBinWidth(first)));
527  fXmax = xaxis->GetBinUpEdge(xaxis->GetLast());
528  TAxis *yaxis = gCurrentHist->GetYaxis();
529  first = yaxis->GetFirst();
530  fYmin = yaxis->GetBinLowEdge(first);
531  if (Hoption.Logy && fYmin <= 0) fYmin = yaxis->GetBinUpEdge(yaxis->FindFixBin(0.01*yaxis->GetBinWidth(first)));
532  fYmax = yaxis->GetBinUpEdge(yaxis->GetLast());
533  fZmax = fGraph2D->GetZmax();
534  fZmin = fGraph2D->GetZmin();
535  if (Hoption.Logz && fZmin <= 0) fZmin = TMath::Min((Double_t)1, (Double_t)0.001*fGraph2D->GetZmax());
536 
537  if (triangles) PaintTriangles(option);
538  if (contour) PaintContour(option);
539  if (line) PaintPolyLine(option);
540  if (err) PaintErrors(option);
541  if (markers) PaintPolyMarker(option);
542 }
543 
544 
545 ////////////////////////////////////////////////////////////////////////////////
546 /// Paints the 2D graph as a contour plot. Delaunay triangles are used
547 /// to compute the contours.
548 
550 {
551  // Initialize the levels on the Z axis
552  Int_t ncolors = gStyle->GetNumberOfColors();
553  Int_t ndiv = gCurrentHist->GetContour();
554  if (ndiv == 0 ) {
555  ndiv = gStyle->GetNumberContours();
556  gCurrentHist->SetContour(ndiv);
557  }
558  Int_t ndivz = TMath::Abs(ndiv);
560 
561  Int_t theColor;
562  TList *l;
563  TGraph *g;
564  TObject *obj;
565  Double_t c;
566 
567  if (!fNdt) FindTriangles();
568 
569  for (Int_t k=0; k<ndiv; k++) {
571  l = GetContourList(c);
572  TIter next(l);
573  while ((obj = next())) {
574  if(obj->InheritsFrom(TGraph::Class()) ) {
575  g=(TGraph*)obj;
578  theColor = Int_t((k+0.99)*Float_t(ncolors)/Float_t(ndivz));
579  g->SetLineColor(gStyle->GetColorPalette(theColor));
580  g->Paint("l");
581  }
582  }
583  }
584 }
585 
586 
587 ////////////////////////////////////////////////////////////////////////////////
588 /// Paints the 2D graph as error bars
589 
591 {
592  Double_t temp1[3],temp2[3];
593 
594  TView *view = gPad->GetView();
595  if (!view) {
596  Error("PaintErrors", "No TView in current pad");
597  return;
598  }
599 
600  Int_t it;
601 
602  Double_t *xm = new Double_t[2];
603  Double_t *ym = new Double_t[2];
604 
608  fGraph2D->TAttLine::Modify();
609 
610  for (it=0; it<fNpoints; it++) {
611  if(fX[it] < fXmin || fX[it] > fXmax) continue;
612  if(fY[it] < fYmin || fY[it] > fYmax) continue;
613  if (fEX) {
614  temp1[0] = fX[it]-fEX[it];
615  temp1[1] = fY[it];
616  temp1[2] = fZ[it];
617  temp1[0] = TMath::Max(temp1[0],fXmin);
618  temp1[1] = TMath::Max(temp1[1],fYmin);
619  temp1[2] = TMath::Max(temp1[2],fZmin);
620  temp1[2] = TMath::Min(temp1[2],fZmax);
621  if (Hoption.Logx) temp1[0] = TMath::Log10(temp1[0]);
622  if (Hoption.Logy) temp1[1] = TMath::Log10(temp1[1]);
623  if (Hoption.Logz) temp1[2] = TMath::Log10(temp1[2]);
624  view->WCtoNDC(temp1, &temp2[0]);
625  xm[0] = temp2[0];
626  ym[0] = temp2[1];
627 
628  temp1[0] = fX[it]+fEX[it];
629  temp1[0] = TMath::Max(temp1[0],fXmin);
630  if (Hoption.Logx) temp1[0] = TMath::Log10(temp1[0]);
631  view->WCtoNDC(temp1, &temp2[0]);
632  xm[1] = temp2[0];
633  ym[1] = temp2[1];
634  gPad->PaintPolyLine(2,xm,ym);
635  }
636  if (fEY) {
637  temp1[0] = fX[it];
638  temp1[1] = fY[it]-fEY[it];
639  temp1[2] = fZ[it];
640  temp1[0] = TMath::Max(temp1[0],fXmin);
641  temp1[1] = TMath::Max(temp1[1],fYmin);
642  temp1[2] = TMath::Max(temp1[2],fZmin);
643  temp1[2] = TMath::Min(temp1[2],fZmax);
644  if (Hoption.Logx) temp1[0] = TMath::Log10(temp1[0]);
645  if (Hoption.Logy) temp1[1] = TMath::Log10(temp1[1]);
646  if (Hoption.Logz) temp1[2] = TMath::Log10(temp1[2]);
647  view->WCtoNDC(temp1, &temp2[0]);
648  xm[0] = temp2[0];
649  ym[0] = temp2[1];
650 
651  temp1[1] = fY[it]+fEY[it];
652  temp1[1] = TMath::Max(temp1[1],fYmin);
653  if (Hoption.Logy) temp1[1] = TMath::Log10(temp1[1]);
654  view->WCtoNDC(temp1, &temp2[0]);
655  xm[1] = temp2[0];
656  ym[1] = temp2[1];
657  gPad->PaintPolyLine(2,xm,ym);
658  }
659  if (fEZ) {
660  temp1[0] = fX[it];
661  temp1[1] = fY[it];
662  temp1[2] = fZ[it]-fEZ[it];
663  temp1[0] = TMath::Max(temp1[0],fXmin);
664  temp1[1] = TMath::Max(temp1[1],fYmin);
665  temp1[2] = TMath::Max(temp1[2],fZmin);
666  temp1[2] = TMath::Min(temp1[2],fZmax);
667  if (Hoption.Logx) temp1[0] = TMath::Log10(temp1[0]);
668  if (Hoption.Logy) temp1[1] = TMath::Log10(temp1[1]);
669  if (Hoption.Logz) temp1[2] = TMath::Log10(temp1[2]);
670  view->WCtoNDC(temp1, &temp2[0]);
671  xm[0] = temp2[0];
672  ym[0] = temp2[1];
673 
674  temp1[2] = fZ[it]+fEZ[it];
675  temp1[2] = TMath::Max(temp1[2],fZmin);
676  temp1[2] = TMath::Min(temp1[2],fZmax);
677  if (Hoption.Logz) temp1[2] = TMath::Log10(temp1[2]);
678  view->WCtoNDC(temp1, &temp2[0]);
679  xm[1] = temp2[0];
680  ym[1] = temp2[1];
681  gPad->PaintPolyLine(2,xm,ym);
682  }
683  }
684  delete [] xm;
685  delete [] ym;
686 }
687 
688 
689 ////////////////////////////////////////////////////////////////////////////////
690 /// Paints one triangle.
691 ///
692 /// - nblev = 0 : paint the color levels
693 /// - nblev != 0 : paint the grid
694 
696  Int_t nblev, Double_t *glev)
697 {
698  Int_t i, fillColor, ncolors, theColor0, theColor2;
699 
700  Int_t p[3];
701  if (fDelaunay) {
702  p[0]=t[0]-1;
703  p[1]=t[1]-1;
704  p[2]=t[2]-1;
705  }
706  else {
707  p[0]=t[0];
708  p[1]=t[1];
709  p[2]=t[2];
710  }
711  Double_t xl[2],yl[2];
712  Double_t zl, r21, r20, r10;
713  Double_t x0 = x[0] , x2 = x[0];
714  Double_t y0 = y[0] , y2 = y[0];
715  Double_t z0 = fZ[p[0]], z2 = fZ[p[0]];
716  Double_t zmin = fGraph2D->GetMinimum();
717  Double_t zmax = fGraph2D->GetMaximum();
718  if (zmin==-1111 && zmax==-1111) {
719  zmin = fZmin;
720  zmax = fZmax;
721  }
722 
723  // Order along Z axis the points (xi,yi,zi) where "i" belongs to {0,1,2}
724  // After this z0 < z1 < z2
725  Int_t i0=0, i1=0, i2=0;
726  if (fZ[p[1]]<=z0) {z0=fZ[p[1]]; x0=x[1]; y0=y[1]; i0=1;}
727  if (fZ[p[1]]>z2) {z2=fZ[p[1]]; x2=x[1]; y2=y[1]; i2=1;}
728  if (fZ[p[2]]<=z0) {z0=fZ[p[2]]; x0=x[2]; y0=y[2]; i0=2;}
729  if (fZ[p[2]]>z2) {z2=fZ[p[2]]; x2=x[2]; y2=y[2]; i2=2;}
730  i1 = 3-i2-i0;
731  Double_t x1 = x[i1];
732  Double_t y1 = y[i1];
733  Double_t z1 = fZ[p[i1]];
734 
735  if (z0>zmax) z0 = zmax;
736  if (z2>zmax) z2 = zmax;
737  if (z0<zmin) z0 = zmin;
738  if (z2<zmin) z2 = zmin;
739  if (z1>zmax) z1 = zmax;
740  if (z1<zmin) z1 = zmin;
741 
742  if (Hoption.Logz) {
743  z0 = TMath::Log10(z0);
744  z1 = TMath::Log10(z1);
745  z2 = TMath::Log10(z2);
746  zmin = TMath::Log10(zmin);
747  zmax = TMath::Log10(zmax);
748  }
749 
750  // zi = Z values of the stripe number i
751  // zip = Previous zi
752  Double_t zi=0, zip=0;
753 
754  if (nblev <= 0) {
755  // Paint the colors levels
756 
757  // Compute the color associated to z0 (theColor0) and z2 (theColor2)
758  ncolors = gStyle->GetNumberOfColors();
759  theColor0 = (Int_t)( ((z0-zmin)/(zmax-zmin))*(ncolors-1) );
760  theColor2 = (Int_t)( ((z2-zmin)/(zmax-zmin))*(ncolors-1) );
761 
762  // The stripes drawn to fill the triangles may have up to 5 points
763  Double_t xp[5], yp[5];
764 
765  // rl = Ratio between z0 and z2 (long)
766  // rs = Ratio between z0 and z1 or z1 and z2 (short)
767  Double_t rl,rs;
768 
769  // ci = Color of the stripe number i
770  // npf = number of point needed to draw the current stripe
771  Int_t ci,npf;
772 
773  fillColor = fGraph2D->GetFillColor();
774 
775  // If the z0's color and z2's colors are the same, the whole triangle
776  // can be painted in one go.
777  if(theColor0 == theColor2) {
779  fGraph2D->TAttFill::Modify();
780  gPad->PaintFillArea(3,x,y);
781 
782  // The triangle must be painted with several colors
783  } else {
784  for(ci=theColor0; ci<=theColor2; ci++) {
786  fGraph2D->TAttFill::Modify();
787  if (ci==theColor0) {
788  zi = (((ci+1)*(zmax-zmin))/(ncolors-1))+zmin;
789  xp[0] = x0;
790  yp[0] = y0;
791  rl = (zi-z0)/(z2-z0);
792  xp[1] = rl*(x2-x0)+x0;
793  yp[1] = rl*(y2-y0)+y0;
794  if (zi>=z1 || z0==z1) {
795  rs = (zi-z1)/(z2-z1);
796  xp[2] = rs*(x2-x1)+x1;
797  yp[2] = rs*(y2-y1)+y1;
798  xp[3] = x1;
799  yp[3] = y1;
800  npf = 4;
801  } else {
802  rs = (zi-z0)/(z1-z0);
803  xp[2] = rs*(x1-x0)+x0;
804  yp[2] = rs*(y1-y0)+y0;
805  npf = 3;
806  }
807  } else if (ci==theColor2) {
808  xp[0] = xp[1];
809  yp[0] = yp[1];
810  xp[1] = x2;
811  yp[1] = y2;
812  if (zi<z1 || z2==z1) {
813  xp[3] = xp[2];
814  yp[3] = yp[2];
815  xp[2] = x1;
816  yp[2] = y1;
817  npf = 4;
818  } else {
819  npf = 3;
820  }
821  } else {
822  zi = (((ci+1)*(zmax-zmin))/(ncolors-1))+zmin;
823  xp[0] = xp[1];
824  yp[0] = yp[1];
825  rl = (zi-z0)/(z2-z0);
826  xp[1] = rl*(x2-x0)+x0;
827  yp[1] = rl*(y2-y0)+y0;
828  if ( zi>=z1 && zip<=z1) {
829  xp[3] = x1;
830  yp[3] = y1;
831  xp[4] = xp[2];
832  yp[4] = yp[2];
833  npf = 5;
834  } else {
835  xp[3] = xp[2];
836  yp[3] = yp[2];
837  npf = 4;
838  }
839  if (zi<z1) {
840  rs = (zi-z0)/(z1-z0);
841  xp[2] = rs*(x1-x0)+x0;
842  yp[2] = rs*(y1-y0)+y0;
843  } else {
844  rs = (zi-z1)/(z2-z1);
845  xp[2] = rs*(x2-x1)+x1;
846  yp[2] = rs*(y2-y1)+y1;
847  }
848  }
849  zip = zi;
850  // Paint a stripe
851  gPad->PaintFillArea(npf,xp,yp);
852  }
853  }
854  fGraph2D->SetFillColor(fillColor);
855  fGraph2D->TAttFill::Modify();
856 
857  } else {
858  // Paint the grid levels
860  fGraph2D->TAttLine::Modify();
861  for(i=0; i<nblev; i++){
862  zl=glev[i];
863  if(zl >= z0 && zl <=z2) {
864  r21=(zl-z1)/(z2-z1);
865  r20=(zl-z0)/(z2-z0);
866  r10=(zl-z0)/(z1-z0);
867  xl[0]=r20*(x2-x0)+x0;
868  yl[0]=r20*(y2-y0)+y0;
869  if(zl >= z1 && zl <=z2) {
870  xl[1]=r21*(x2-x1)+x1;
871  yl[1]=r21*(y2-y1)+y1;
872  } else {
873  xl[1]=r10*(x1-x0)+x0;
874  yl[1]=r10*(y1-y0)+y0;
875  }
876  gPad->PaintPolyLine(2,xl,yl);
877  }
878  }
880  fGraph2D->TAttLine::Modify();
881  }
882 }
883 
884 
885 ////////////////////////////////////////////////////////////////////////////////
886 /// Paints the 2D graph as PaintPolyMarker
887 
889 {
890  Double_t temp1[3],temp2[3];
891 
892  TView *view = gPad->GetView();
893  if (!view) {
894  Error("PaintPolyMarker", "No TView in current pad");
895  return;
896  }
897 
898  TString opt = option;
899  opt.ToLower();
900  Bool_t markers0 = opt.Contains("p0");
901  Bool_t colors = opt.Contains("pcol");
902  Int_t ncolors = gStyle->GetNumberOfColors();
903  Int_t it, theColor;
904 
905  // Initialize the levels on the Z axis
906  if (colors) {
907  Int_t ndiv = gCurrentHist->GetContour();
908  if (ndiv == 0 ) {
909  ndiv = gStyle->GetNumberContours();
910  gCurrentHist->SetContour(ndiv);
911  }
913  }
914 
915  Double_t *xm = new Double_t[fNpoints];
916  Double_t *ym = new Double_t[fNpoints];
917  Double_t *zm = new Double_t[fNpoints];
918  Double_t hzmin = gCurrentHist->GetMinimum();
919  Double_t hzmax = gCurrentHist->GetMaximum();
920 
921  Double_t Xeps = (fXmax-fXmin)*0.0001;
922  Double_t Yeps = (fYmax-fYmin)*0.0001;
923  Double_t Zeps = (hzmax-hzmin)*0.0001;
924 
925  Int_t npd = 0;
926  for (it=0; it<fNpoints; it++) {
927  xm[it] = 0;
928  ym[it] = 0;
929  if(fXmin - fX[it] > Xeps || fX[it] - fXmax > Xeps) continue;
930  if(fYmin - fY[it] > Yeps || fY[it] - fYmax > Yeps) continue;
931  if(hzmin - fZ[it] > Zeps || fZ[it] - hzmax > Zeps) continue;
932  temp1[0] = fX[it];
933  temp1[1] = fY[it];
934  temp1[2] = fZ[it];
935  temp1[0] = TMath::Max(temp1[0],fXmin);
936  temp1[1] = TMath::Max(temp1[1],fYmin);
937  temp1[2] = TMath::Max(temp1[2],hzmin);
938  temp1[2] = TMath::Min(temp1[2],hzmax);
939  if (Hoption.Logx) temp1[0] = TMath::Log10(temp1[0]);
940  if (Hoption.Logy) temp1[1] = TMath::Log10(temp1[1]);
941  if (Hoption.Logz) temp1[2] = TMath::Log10(temp1[2]);
942  view->WCtoNDC(temp1, &temp2[0]);
943  xm[npd] = temp2[0];
944  ym[npd] = temp2[1];
945  zm[npd] = fZ[it];
946  npd++;
947  }
948  if (markers0) {
949  PaintPolyMarker0(npd,xm,ym);
950  } else if (colors) {
951  Int_t cols = fGraph2D->GetMarkerColor();
952  for (it=0; it<npd; it++) {
953  theColor = (Int_t)( ((zm[it]-hzmin)/(hzmax-hzmin))*(ncolors-1) );
955  fGraph2D->TAttMarker::Modify();
956  gPad->PaintPolyMarker(1,&xm[it],&ym[it]);
957  }
958  fGraph2D->SetMarkerColor(cols);
959  } else {
963  fGraph2D->TAttMarker::Modify();
964  gPad->PaintPolyMarker(npd,xm,ym);
965  }
966  delete [] xm;
967  delete [] ym;
968  delete [] zm;
969 }
970 
971 
972 ////////////////////////////////////////////////////////////////////////////////
973 /// Paints the 2D graph as PaintPolyLine
974 
976 {
977  Double_t temp1[3],temp2[3];
978 
979  TView *view = gPad->GetView();
980  if (!view) {
981  Error("PaintPolyLine", "No TView in current pad");
982  return;
983  }
984 
985  Int_t it;
986 
987  Double_t *xm = new Double_t[fNpoints];
988  Double_t *ym = new Double_t[fNpoints];
989  Int_t npd = 0;
990  for (it=0; it<fNpoints; it++) {
991  if(fX[it] < fXmin || fX[it] > fXmax) continue;
992  if(fY[it] < fYmin || fY[it] > fYmax) continue;
993  npd++;
994  temp1[0] = fX[it];
995  temp1[1] = fY[it];
996  temp1[2] = fZ[it];
997  temp1[0] = TMath::Max(temp1[0],fXmin);
998  temp1[1] = TMath::Max(temp1[1],fYmin);
999  temp1[2] = TMath::Max(temp1[2],fZmin);
1000  temp1[2] = TMath::Min(temp1[2],fZmax);
1001  if (Hoption.Logx) temp1[0] = TMath::Log10(temp1[0]);
1002  if (Hoption.Logy) temp1[1] = TMath::Log10(temp1[1]);
1003  if (Hoption.Logz) temp1[2] = TMath::Log10(temp1[2]);
1004  view->WCtoNDC(temp1, &temp2[0]);
1005  xm[it] = temp2[0];
1006  ym[it] = temp2[1];
1007  }
1011  fGraph2D->TAttLine::Modify();
1012  gPad->PaintPolyLine(npd,xm,ym);
1013  delete [] xm;
1014  delete [] ym;
1015 }
1016 
1017 
1018 ////////////////////////////////////////////////////////////////////////////////
1019 /// Paints a circle at each vertex. Each circle background is white.
1020 
1022 {
1024  Int_t mc = fGraph2D->GetMarkerColor();
1025  Int_t ms = fGraph2D->GetMarkerStyle();
1026  for (Int_t i=0; i<n; i++) {
1027  fGraph2D->SetMarkerStyle(20);
1029  fGraph2D->TAttMarker::Modify();
1030  gPad->PaintPolyMarker(1,&x[i],&y[i]);
1031  fGraph2D->SetMarkerStyle(24);
1032  fGraph2D->SetMarkerColor(mc);
1033  fGraph2D->TAttMarker::Modify();
1034  gPad->PaintPolyMarker(1,&x[i],&y[i]);
1035  }
1036  fGraph2D->SetMarkerStyle(ms);
1037 }
1038 
1039 
1040 ////////////////////////////////////////////////////////////////////////////////
1041 /// Paints the 2D graph as triangles
1043 {
1044  if (fDelaunay)
1045  PaintTriangles_old(option);
1046  else if (fDelaunay2D)
1047  PaintTriangles_new(option);
1048 }
1049 
1050 
1052 {
1053  Double_t x[4], y[4], temp1[3],temp2[3];
1054  Int_t it,t[3];
1055  Int_t *order = 0;
1056  Double_t *dist = 0;
1057 
1058  TView *view = gPad->GetView();
1059  if (!view) {
1060  Error("PaintTriangles", "No TView in current pad");
1061  return;
1062  }
1063 
1064  TString opt = option;
1065  opt.ToLower();
1066  Bool_t tri1 = opt.Contains("tri1");
1067  Bool_t tri2 = opt.Contains("tri2");
1068  Bool_t markers = opt.Contains("p");
1069  Bool_t markers0 = opt.Contains("p0");
1070  Bool_t wire = opt.Contains("w");
1071 
1072  // Define the grid levels drawn on the triangles.
1073  // The grid levels are aligned on the Z axis' main tick marks.
1074  Int_t nblev=0;
1075  Double_t *glev=0;
1076  if (!tri1 && !tri2 && !wire) {
1077  Int_t ndivz = gCurrentHist->GetZaxis()->GetNdivisions()%100;
1078  Int_t nbins;
1079  Double_t binLow = 0, binHigh = 0, binWidth = 0;
1080 
1081  // Find the main tick marks positions.
1082  Double_t *r0 = view->GetRmin();
1083  Double_t *r1 = view->GetRmax();
1084  if (!r0 || !r1) return;
1085 
1086  if (ndivz > 0) {
1087  THLimitsFinder::Optimize(r0[2], r1[2], ndivz,
1088  binLow, binHigh, nbins, binWidth, " ");
1089  } else {
1090  nbins = TMath::Abs(ndivz);
1091  binLow = r0[2];
1092  binHigh = r1[2];
1093  binWidth = (binHigh-binLow)/nbins;
1094  }
1095  // Define the grid levels
1096  nblev = nbins+1;
1097  glev = new Double_t[nblev];
1098  for (Int_t i = 0; i < nblev; ++i) glev[i] = binLow+i*binWidth;
1099  }
1100 
1101  // Initialize the levels on the Z axis
1102  if (tri1 || tri2) {
1103  Int_t ndiv = gCurrentHist->GetContour();
1104  if (ndiv == 0 ) {
1105  ndiv = gStyle->GetNumberContours();
1106  gCurrentHist->SetContour(ndiv);
1107  }
1109  }
1110 
1111  // For each triangle, compute the distance between the triangle centre
1112  // and the back planes. Then these distances are sorted in order to draw
1113  // the triangles from back to front.
1114  if (!fNdt) FindTriangles();
1115  Double_t cp = TMath::Cos(view->GetLongitude()*TMath::Pi()/180.);
1116  Double_t sp = TMath::Sin(view->GetLongitude()*TMath::Pi()/180.);
1117  order = new Int_t[fNdt];
1118  dist = new Double_t[fNdt];
1119  Double_t xd,yd;
1120  Int_t p, n, m;
1121  Bool_t o = kFALSE;
1122  for (it=0; it<fNdt; it++) {
1123  p = fPTried[it];
1124  n = fNTried[it];
1125  m = fMTried[it];
1126  xd = (fXN[p]+fXN[n]+fXN[m])/3;
1127  yd = (fYN[p]+fYN[n]+fYN[m])/3;
1128  if ((cp >= 0) && (sp >= 0.)) {
1129  dist[it] = -(fXNmax-xd+fYNmax-yd);
1130  } else if ((cp <= 0) && (sp >= 0.)) {
1131  dist[it] = -(fXNmax-xd+yd-fYNmin);
1132  o = kTRUE;
1133  } else if ((cp <= 0) && (sp <= 0.)) {
1134  dist[it] = -(xd-fXNmin+yd-fYNmin);
1135  } else {
1136  dist[it] = -(xd-fXNmin+fYNmax-yd);
1137  o = kTRUE;
1138  }
1139  }
1140  TMath::Sort(fNdt, dist, order, o);
1141 
1142  // Draw the triangles and markers if requested
1144  Int_t fs = fGraph2D->GetFillStyle();
1145  fGraph2D->SetFillStyle(1001);
1146  fGraph2D->TAttFill::Modify();
1148  fGraph2D->TAttLine::Modify();
1149  int lst = fGraph2D->GetLineStyle();
1150  for (it=0; it<fNdt; it++) {
1151  t[0] = fPTried[order[it]];
1152  t[1] = fNTried[order[it]];
1153  t[2] = fMTried[order[it]];
1154  for (Int_t k=0; k<3; k++) {
1155  if(fX[t[k]-1] < fXmin || fX[t[k]-1] > fXmax) goto endloop;
1156  if(fY[t[k]-1] < fYmin || fY[t[k]-1] > fYmax) goto endloop;
1157  temp1[0] = fX[t[k]-1];
1158  temp1[1] = fY[t[k]-1];
1159  temp1[2] = fZ[t[k]-1];
1160  temp1[0] = TMath::Max(temp1[0],fXmin);
1161  temp1[1] = TMath::Max(temp1[1],fYmin);
1162  temp1[2] = TMath::Max(temp1[2],fZmin);
1163  temp1[2] = TMath::Min(temp1[2],fZmax);
1164  if (Hoption.Logx) temp1[0] = TMath::Log10(temp1[0]);
1165  if (Hoption.Logy) temp1[1] = TMath::Log10(temp1[1]);
1166  if (Hoption.Logz) temp1[2] = TMath::Log10(temp1[2]);
1167  view->WCtoNDC(temp1, &temp2[0]);
1168  x[k] = temp2[0];
1169  y[k] = temp2[1];
1170  }
1171  x[3] = x[0];
1172  y[3] = y[0];
1173  if (tri1 || tri2) PaintLevels(t,x,y);
1174  if (!tri1 && !tri2 && !wire) {
1175  gPad->PaintFillArea(3,x,y);
1176  PaintLevels(t,x,y,nblev,glev);
1177  }
1178  if (!tri2) gPad->PaintPolyLine(4,x,y);
1179  if (markers) {
1180  if (markers0) {
1181  PaintPolyMarker0(3,x,y);
1182  } else {
1186  fGraph2D->TAttMarker::Modify();
1187  gPad->PaintPolyMarker(3,x,y);
1188  }
1189  }
1190 endloop:
1191  continue;
1192  }
1193  fGraph2D->SetFillStyle(fs);
1194  fGraph2D->SetLineStyle(lst);
1195  fGraph2D->TAttLine::Modify();
1196  fGraph2D->TAttFill::Modify();
1197  delete [] order;
1198  delete [] dist;
1199  if (glev) delete [] glev;
1200 }
1201 
1202 
1203 /////////
1204 // Paints the 2D graph as triangles (new implementation)
1205 /////
1207 {
1208 
1209  Double_t x[4], y[4], temp1[3],temp2[3];
1210  Int_t p[3];
1211 
1212  TView *view = gPad->GetView();
1213  if (!view) {
1214  Error("PaintTriangles", "No TView in current pad");
1215  return;
1216  }
1217 
1218  TString opt = option;
1219  opt.ToLower();
1220  Bool_t tri1 = opt.Contains("tri1");
1221  Bool_t tri2 = opt.Contains("tri2");
1222  Bool_t markers = opt.Contains("p");
1223  Bool_t markers0 = opt.Contains("p0");
1224  Bool_t wire = opt.Contains("w");
1225 
1226  // Define the grid levels drawn on the triangles.
1227  // The grid levels are aligned on the Z axis' main tick marks.
1228  Int_t nblev=0;
1229  Double_t *glev=0;
1230  if (!tri1 && !tri2 && !wire) {
1231  Int_t ndivz = gCurrentHist->GetZaxis()->GetNdivisions()%100;
1232  Int_t nbins;
1233  Double_t binLow = 0, binHigh = 0, binWidth = 0;
1234 
1235  // Find the main tick marks positions.
1236  Double_t *r0 = view->GetRmin();
1237  Double_t *r1 = view->GetRmax();
1238  if (!r0 || !r1) return;
1239 
1240  if (ndivz > 0) {
1241  THLimitsFinder::Optimize(r0[2], r1[2], ndivz,
1242  binLow, binHigh, nbins, binWidth, " ");
1243  } else {
1244  nbins = TMath::Abs(ndivz);
1245  binLow = r0[2];
1246  binHigh = r1[2];
1247  binWidth = (binHigh-binLow)/nbins;
1248  }
1249  // Define the grid levels
1250  nblev = nbins+1;
1251  glev = new Double_t[nblev];
1252  for (Int_t i = 0; i < nblev; ++i) glev[i] = binLow+i*binWidth;
1253  }
1254 
1255  // Initialize the levels on the Z axis
1256  if (tri1 || tri2) {
1257  Int_t ndiv = gCurrentHist->GetContour();
1258  if (ndiv == 0 ) {
1259  ndiv = gStyle->GetNumberContours();
1260  gCurrentHist->SetContour(ndiv);
1261  }
1263  }
1264 
1265  // For each triangle, compute the distance between the triangle centre
1266  // and the back planes. Then these distances are sorted in order to draw
1267  // the triangles from back to front.
1268  if (!fNdt) FindTriangles();
1269  Double_t cp = TMath::Cos(view->GetLongitude()*TMath::Pi()/180.);
1270  Double_t sp = TMath::Sin(view->GetLongitude()*TMath::Pi()/180.);
1271 
1272  Bool_t reverse = kFALSE;
1273  std::function<Double_t(Double_t, Double_t)> fDist;
1274 
1275  if ((cp >= 0) && (sp >= 0.)) {
1276  fDist = [&](Double_t xd, Double_t yd) -> Double_t { return -(fXNmax-xd+fYNmax-yd);};
1277  } else if ((cp <= 0) && (sp >= 0.)) {
1278  fDist = [&](Double_t xd, Double_t yd) -> Double_t { return -(fXNmax-xd+yd-fYNmin);};
1279  reverse = kTRUE;
1280  } else if ((cp <= 0) && (sp <= 0.)) {
1281  fDist = [&](Double_t xd, Double_t yd) -> Double_t { return -(xd-fXNmin+yd-fYNmin);};
1282  } else {
1283  fDist = [&](Double_t xd, Double_t yd) -> Double_t { return -(xd-fXNmin+fYNmax-yd);};
1284  reverse = kTRUE;
1285  }
1286 
1287  typedef std::pair<Double_t, TGraphDelaunay2D::Triangles::const_iterator> DistEntry;
1288  std::vector<DistEntry> dist;
1289  for(auto it = fDelaunay2D->begin(); it != fDelaunay2D->end(); ++it){
1290  auto face = *it;
1291  Double_t xd = (face.x[0] + face.x[1] + face.x[2]) / 3;
1292  Double_t yd = (face.y[0] + face.y[1] + face.y[2]) / 3;
1293 
1294  dist.emplace_back(fDist(xd, yd), it);
1295  }
1296 
1297  std::sort(dist.begin(), dist.end(),
1298  [&](const DistEntry & a, const DistEntry & b){ return !reverse ? (a.first < b.first) : (b.first < a .first); });
1299 
1300  // Draw the triangles and markers if requested
1302  Int_t fs = fGraph2D->GetFillStyle();
1303  fGraph2D->SetFillStyle(1001);
1304  fGraph2D->TAttFill::Modify();
1306  fGraph2D->TAttLine::Modify();
1307  int lst = fGraph2D->GetLineStyle();
1308  for (const auto & it : dist) {
1309  p[0] = it.second->idx[0];
1310  p[1] = it.second->idx[1];
1311  p[2] = it.second->idx[2];
1312  for (Int_t k=0; k<3; k++) {
1313  if(fX[p[k]] < fXmin || fX[p[k]] > fXmax) goto endloop;
1314  if(fY[p[k]] < fYmin || fY[p[k]] > fYmax) goto endloop;
1315  temp1[0] = fX[p[k]];
1316  temp1[1] = fY[p[k]];
1317  temp1[2] = fZ[p[k]];
1318  temp1[0] = TMath::Max(temp1[0],fXmin);
1319  temp1[1] = TMath::Max(temp1[1],fYmin);
1320  temp1[2] = TMath::Max(temp1[2],fZmin);
1321  temp1[2] = TMath::Min(temp1[2],fZmax);
1322  if (Hoption.Logx) temp1[0] = TMath::Log10(temp1[0]);
1323  if (Hoption.Logy) temp1[1] = TMath::Log10(temp1[1]);
1324  if (Hoption.Logz) temp1[2] = TMath::Log10(temp1[2]);
1325  view->WCtoNDC(temp1, &temp2[0]);
1326  x[k] = temp2[0];
1327  y[k] = temp2[1];
1328  }
1329  x[3] = x[0];
1330  y[3] = y[0];
1331  if (tri1 || tri2) PaintLevels(p,x,y);
1332  if (!tri1 && !tri2 && !wire) {
1333  gPad->PaintFillArea(3,x,y);
1334  PaintLevels(p,x,y,nblev,glev);
1335  }
1336  if (!tri2) gPad->PaintPolyLine(4,x,y);
1337  if (markers) {
1338  if (markers0) {
1339  PaintPolyMarker0(3,x,y);
1340  } else {
1344  fGraph2D->TAttMarker::Modify();
1345  gPad->PaintPolyMarker(3,x,y);
1346  }
1347  }
1348 endloop:
1349  continue;
1350  }
1351  fGraph2D->SetFillStyle(fs);
1352  fGraph2D->SetLineStyle(lst);
1353  fGraph2D->TAttLine::Modify();
1354  fGraph2D->TAttFill::Modify();
1355 
1356  if (glev) delete [] glev;
1357 }
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
Definition: TAttLine.h:43
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
virtual Double_t GetMaximum(Double_t maxval=FLT_MAX) const
Return maximum value smaller than maxval of bins in the range, unless the value has been overridden b...
Definition: TH1.cxx:7666
TGraph2D * GetGraph2D() const
Int_t * fPTried
Equal to fDelaunay->fNdt.
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition: TAxis.cxx:444
Int_t GetNumberContours() const
Definition: TStyle.h:225
TLine * line
Histogram option structure.
Definition: Hoption.h:24
virtual void WCtoNDC(const Float_t *pw, Float_t *pn)=0
float Float_t
Definition: RtypesCore.h:53
const char Option_t
Definition: RtypesCore.h:62
virtual Double_t * GetRmax()=0
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition: TAxis.cxx:504
virtual void SetContour(Int_t nlevels, const Double_t *levels=0)
Set the number and values of contour levels.
Definition: TH1.cxx:7607
R__EXTERN TStyle * gStyle
Definition: TStyle.h:402
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:159
int Logy
log scale in Y. Also set by histogram option
Definition: Hoption.h:67
Int_t * GetNTried() const
static void Optimize(Double_t A1, Double_t A2, Int_t nold, Double_t &BinLow, Double_t &BinHigh, Int_t &nbins, Double_t &BWID, Option_t *option="")
static function to compute reasonable axis limits
See TView3D.
Definition: TView.h:25
Double_t GetXNmin() const
void PaintPolyLine(Option_t *option)
Paints the 2D graph as PaintPolyLine.
Double_t fXNmax
Equal to fDelaunay->fXNmin.
Basic string class.
Definition: TString.h:129
void PaintPolyMarker0(Int_t n, Double_t *x, Double_t *y)
Paints a circle at each vertex. Each circle background is white.
Double_t GetZmin() const
Returns the Z minimum.
Definition: TGraph2D.cxx:1252
void PaintLevels(Int_t *v, Double_t *x, Double_t *y, Int_t nblev=0, Double_t *glev=0)
Paints one triangle.
R__EXTERN Hoption_t Hoption
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:168
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1099
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
TArc * a
Definition: textangle.C:12
virtual void SetFillStyle(Style_t fstyle)
Set the fill area style.
Definition: TAttFill.h:39
Int_t * GetPTried() const
int nbins[3]
void Paint(Option_t *option)
Paint a TGraphDelaunay according to the value of "option":
int Logx
log scale in X. Also set by histogram option
Definition: Hoption.h:66
Short_t Abs(Short_t d)
Definition: TMathBase.h:108
virtual Width_t GetLineWidth() const
Return the line width.
Definition: TAttLine.h:35
Double_t GetMinimum() const
Definition: TGraph2D.h:113
Double_t GetYNmax() const
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition: TAxis.cxx:514
virtual Style_t GetMarkerStyle() const
Return the marker style.
Definition: TAttMarker.h:32
TGraphDelaunay2D * fDelaunay2D
virtual Style_t GetLineStyle() const
Return the line style.
Definition: TAttLine.h:34
virtual Int_t GetContour(Double_t *levels=0)
Return contour values into array levels if pointer levels is non zero.
Definition: TH1.cxx:7535
static const double x2[5]
void PaintTriangles_new(Option_t *option)
Double_t x[n]
Definition: legend1.C:17
virtual void Paint(Option_t *chopt="")
Draw this graph with its current attributes.
Definition: TGraph.cxx:1936
Double_t * fXN
Pointer to fGraph2D->fZ.
void Class()
Definition: Class.C:29
Int_t fNdt
Equal to fGraph2D->fNpoints.
TGraph2D * GetGraph2D() const
virtual Double_t * GetEY() const
Definition: TGraph2D.h:122
Double_t * fY
Pointer to fGraph2D->fX.
Double_t * fYN
Pointer to fDelaunay->fXN.
Double_t GetXNmax() const
Double_t Log10(Double_t x)
Definition: TMath.h:652
static double p2(double t, double a, double b, double c)
virtual void SetMarkerColor(Color_t mcolor=1)
Set the marker color.
Definition: TAttMarker.h:38
Double_t GetXNmin() const
void Sort(Index n, const Element *a, Index *index, Bool_t down=kTRUE)
Definition: TMath.h:1151
virtual Size_t GetMarkerSize() const
Return the marker size.
Definition: TAttMarker.h:33
Double_t * fZ
Pointer to fGraph2D->fY.
Int_t GetColorPalette(Int_t i) const
Return color number i in current palette.
Definition: TStyle.cxx:735
constexpr Double_t Pi()
Definition: TMath.h:40
virtual Double_t * GetEZ() const
Definition: TGraph2D.h:123
user specified contour levels
Definition: TH1.h:149
virtual Int_t GetNdivisions() const
Definition: TAttAxis.h:36
A doubly linked list.
Definition: TList.h:43
Int_t GetNdt() const
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition: TAttLine.h:40
Double_t fYmax
fGraph2D->fHistogram limits
Int_t GetLast() const
Return last bin on the axis i.e.
Definition: TAxis.cxx:455
Class to manage histogram axis.
Definition: TAxis.h:30
TGraph2D * fGraph2D
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition: TAttFill.h:37
unsigned int r1[N_CITIES]
Definition: simanTSP.cxx:321
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:436
Triangles::const_iterator end() const
Int_t GetNdt() const
void PaintTriangles(Option_t *option)
Paints the 2D graph as triangles.
TMarker * m
Definition: textangle.C:8
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:873
Double_t GetMaximum() const
Definition: TGraph2D.h:112
Double_t fXNmin
Pointer to fGraph2D->fZE.
TLine * l
Definition: textangle.C:4
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
Definition: TAttMarker.h:40
virtual Double_t GetContourLevelPad(Int_t level) const
Return the value of contour number "level" in Pad coordinates.
Definition: TH1.cxx:7564
TAxis * GetYaxis()
Definition: TH1.h:301
static double p1(double t, double a, double b)
void FindTriangles()
Find triangles in fDelaunay and initialise the TGraph2DPainter values needed to paint triangles or fi...
Triangles::const_iterator begin() const
Definition: graph.py:1
Int_t GetNumberOfColors() const
Return number of colors in the color palette.
Definition: TStyle.cxx:801
virtual void SetMarkerSize(Size_t msize=1)
Set the marker size.
Definition: TAttMarker.h:41
virtual Double_t * GetRmin()=0
virtual Double_t GetLongitude()=0
TGraph2DPainter()
TGraph2DPainter default constructor.
Double_t Cos(Double_t)
Definition: TMath.h:551
virtual Double_t GetMinimum(Double_t minval=-FLT_MAX) const
Return minimum value larger than minval of bins in the range, unless the value has been overridden by...
Definition: TH1.cxx:7751
const Bool_t kFALSE
Definition: RtypesCore.h:92
virtual Double_t * GetEX() const
Definition: TGraph2D.h:121
Double_t * GetY() const
Definition: TGraph2D.h:119
Double_t GetZmax() const
Returns the Z maximum.
Definition: TGraph2D.cxx:1241
virtual Color_t GetLineColor() const
Return the line color.
Definition: TAttLine.h:33
void PaintErrors(Option_t *option)
Paints the 2D graph as error bars.
Int_t * fNTried
Pointer to fDelaunay->fPTried.
Color * colors
Definition: X3DBuffer.c:19
static const double x1[5]
#define ClassImp(name)
Definition: Rtypes.h:336
double Double_t
Definition: RtypesCore.h:55
Double_t fYNmin
Equal to fDelaunay->fXNmax.
Double_t fYNmax
Equal to fDelaunay->fYNmin.
Double_t * fEX
Pointer to fDelaunay->fYN.
void PaintContour(Option_t *option)
Paints the 2D graph as a contour plot.
TGraphDelaunay * fDelaunay
Pointer to fDelaunay->fMTried.
Double_t y[n]
Definition: legend1.C:17
virtual Color_t GetFillColor() const
Return the fill area color.
Definition: TAttFill.h:30
TGraphDelaunay2D generates a Delaunay triangulation of a TGraph2D.
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:572
Double_t * GetZ() const
Definition: TGraph2D.h:120
The TH1 histogram class.
Definition: TH1.h:56
TList * GetContourList(Double_t contour)
Returns the X and Y graphs building a contour.
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition: TAttLine.h:42
TAxis * GetZaxis()
Definition: TH1.h:302
Int_t * GetMTried() const
Mother of all ROOT objects.
Definition: TObject.h:37
virtual Int_t FindFixBin(Double_t x) const
Find bin number corresponding to abscissa x.
Definition: TAxis.cxx:405
#define R__EXTERN
Definition: DllImport.h:27
Double_t * GetXN() const
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition: TAxis.cxx:526
virtual void SetPoint(Int_t i, Double_t x, Double_t y)
Set x and y values for point number i.
Definition: TGraph.cxx:2156
Int_t * fMTried
Pointer to fDelaunay->fNTried.
Double_t * fEY
Pointer to fGraph2D->fXE.
virtual void Add(TObject *obj)
Definition: TList.h:77
void PaintTriangles_old(Option_t *option)
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:200
A Graph is a graphics object made of two arrays X and Y with npoints each.
Definition: TGraph.h:41
Double_t Sin(Double_t)
Definition: TMath.h:548
void PaintPolyMarker(Option_t *option)
Paints the 2D graph as PaintPolyMarker.
Int_t GetN() const
Definition: TGraph2D.h:117
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
R__EXTERN TH1 * gCurrentHist
#define gPad
Definition: TVirtualPad.h:284
Double_t * GetYN() const
Double_t * fEZ
Pointer to fGraph2D->fYE.
The TGraphDelaunay painting class.
virtual Color_t GetMarkerColor() const
Return the marker color.
Definition: TAttMarker.h:31
Definition: first.py:1
Double_t GetYNmin() const
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition: TAttFill.h:31
void FindAllTriangles()
Attempt to find all the Delaunay triangles of the point set.
const Bool_t kTRUE
Definition: RtypesCore.h:91
Double_t GetXNmax() const
const Int_t n
Definition: legend1.C:16
int Logz
log scale in Z. Also set by histogram option
Definition: Hoption.h:68
TAxis * GetXaxis()
Definition: TH1.h:300
TGraphDelaunay generates a Delaunay triangulation of a TGraph2D.
Double_t * GetX() const
Definition: TGraph2D.h:118
Double_t fXmin
Equal to fDelaunay->fYNmax.
virtual ~TGraph2DPainter()
TGraph2DPainter destructor.
Double_t GetYNmin() const
Double_t GetYNmax() const