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