Logo ROOT  
Reference Guide
TGraphPolargram.cxx
Go to the documentation of this file.
1// @(#)root/graf:$Id$
2// Author: Sebastian Boser, Mathieu Demaret 02/02/06
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/** \class TGraphPolargram
13\ingroup BasicGraphics
14
15To draw polar axis
16
17TGraphPolargram draw the polar axis of the TGraphPolar.
18
19Example:
20
21Begin_Macro(source)
22{
23 TCanvas * CPol = new TCanvas("CPol","TGraphPolar Examples",500,500);
24
25 Double_t rmin=0;
26 Double_t rmax=TMath::Pi()*2;
27 Double_t r[1000];
28 Double_t theta[1000];
29
30 TF1 * fp1 = new TF1("fplot","cos(x)",rmin,rmax);
31 for (Int_t ipt = 0; ipt < 1000; ipt++) {
32 r[ipt] = ipt*(rmax-rmin)/1000+rmin;
33 theta[ipt] = fp1->Eval(r[ipt]);
34 }
35 TGraphPolar * grP1 = new TGraphPolar(1000,r,theta);
36 grP1->SetTitle("");
37 grP1->SetLineColor(2);
38 grP1->Draw("AOL");
39}
40End_Macro
41*/
42
43#include "TGraphPolar.h"
44#include "TGraphPolargram.h"
45#include "TGaxis.h"
46#include "THLimitsFinder.h"
47#include "TVirtualPad.h"
48#include "TLatex.h"
49#include "TEllipse.h"
50#include "TMath.h"
51
53
54////////////////////////////////////////////////////////////////////////////////
55/// TGraphPolargram Constructor.
56
58 Double_t tmin, Double_t tmax):
59 TNamed(name,"Polargram")
60{
61 Init();
62 fNdivRad = 508;
63 fNdivPol = 508;
64 fPolarLabels = nullptr;
65 fRwrmax = rmax;
66 fRwrmin = rmin;
67 fRwtmin = tmin;
68 fRwtmax = tmax;
69}
70
71////////////////////////////////////////////////////////////////////////////////
72/// Short constructor used in the case of a spider plot.
73
75 TNamed(name,"Polargram")
76{
77 Init();
78 fNdivRad = 0;
79 fNdivPol = 0;
80 fPolarLabels = nullptr;
81 fRwrmax = 1;
82 fRwrmin = 0;
83 fRwtmax = 0;
84 fRwtmin = 0;
85}
86
87////////////////////////////////////////////////////////////////////////////////
88/// TGraphPolargram destructor.
89
91{
92 if (fPolarLabels) delete [] fPolarLabels;
93}
94
95////////////////////////////////////////////////////////////////////////////////
96/// Set the Polar range.
97/// \param[in] tmin the start number.
98/// \param[in] tmax the end number.
99
101{
102 if (tmin < tmax) {
103 fRwtmin = tmin;
104 fRwtmax = tmax;
105 }
106 if (gPad) gPad->Modified();
107}
108
109////////////////////////////////////////////////////////////////////////////////
110/// Everything within the circle belongs to the TGraphPolargram.
111
113{
114 Int_t i;
115 Double_t x = gPad->AbsPixeltoX(px);
116 Double_t y = gPad->AbsPixeltoY(py);
117
118 // Check if close to a (major) radial line.
120 Int_t div = (Int_t)rad*(fNdivRad%100);
121 Double_t dr = TMath::Min(TMath::Abs(rad-div*1./(fNdivRad%100)),
122 TMath::Abs(rad-(div+1)*1./(fNdivRad%100)));
123 Int_t drad = gPad->XtoPixel(dr)-gPad->XtoPixel(0);
124
125 // Check if close to a (major) Polar line.
126 // This is not a proper calculation, but rather fast.
127 Int_t dt = kMaxPixel;
128 for (i=0; i<(fNdivPol%100); i++) {
129 Double_t theta = i*2*TMath::Pi()/(fNdivPol%100);
130
131 // Attention: px,py in pixel units, line given in user coordinates.
132 Int_t dthis = DistancetoLine(px,py,0.,0.,TMath::Cos(theta),
133 TMath::Sin(theta));
134
135 // Fails if we are outside box described by the line.
136 // (i.e for all hor/vert lines)
137 if (dthis==9999) {
138
139 // Outside -> Get distance to endpoint of line.
140 if (rad>1) {
141 dthis = (Int_t)TMath::Sqrt(
142 TMath::Power(px-gPad->XtoPixel(TMath::Cos(theta)),2)+
143 TMath::Power(py-gPad->YtoPixel(TMath::Sin(theta)),2));
144 } else {
145
146 // Check for horizontal line.
147 if (((TMath::Abs(theta-TMath::Pi())<0.1) &&
148 ((px-gPad->XtoPixel(0))<0)) ||
149 ((TMath::Abs(theta)<0.1) &&
150 ((px-gPad->XtoPixel(0))>0))) {
151 dthis = TMath::Abs(py-gPad->YtoPixel(0.));
152 }
153
154 //Check for vertical line.
155 if (((TMath::Abs(theta-TMath::PiOver2())<0.1) &&
156 ((py-gPad->YtoPixel(0))>0)) ||
157 ((TMath::Abs(theta-3*TMath::PiOver2())<0.1) &&
158 (py-gPad->YtoPixel(0))<0)) {
159 dthis = TMath::Abs(px-gPad->XtoPixel(0.));
160 }
161 if (dthis==9999) {
162
163 // Inside, but out of box for nonorthogonal line ->
164 // get distance to start point.
165 dthis = (Int_t)TMath::Sqrt(
166 TMath::Power(px-gPad->XtoPixel(0.),2)+
167 TMath::Power(py-gPad->YtoPixel(0.),2));
168 }
169 }
170 }
171
172 // Take distance to closes line.
173 dt = TMath::Min(dthis,dt);
174 }
175 return TMath::Min(drad, dt);
176}
177
178////////////////////////////////////////////////////////////////////////////////
179/// Draw Polargram.
180
182{
183 Paint(options);
184 AppendPad(options);
185}
186
187////////////////////////////////////////////////////////////////////////////////
188/// Indicate that there is something to click here.
189
191{
192 if (!gPad) return;
193
194 Int_t kMaxDiff = 20;
195 static Int_t d1, d2, d3, px1, py1, px3, py3;
196 static Bool_t p1, p2, p3, p4, p5, p6, p7, p8;
197 Double_t px2, py2;
198 p2 = p3 = p4 = p5 = p6 = p7 = p8 = kFALSE;
199 if (!gPad->IsEditable()) return;
200 switch (event) {
201 case kMouseMotion:
202 px1 = gPad->XtoAbsPixel(TMath::Cos(GetAngle()));
203 py1 = gPad->YtoAbsPixel(TMath::Sin(GetAngle()));
204 d1 = TMath::Abs(px1 - px) + TMath::Abs(py1-py); //simply take sum of pixels differences
205 p1 = kFALSE;
206 px2 = gPad->XtoAbsPixel(-1);
207 py2 = gPad->YtoAbsPixel(1);
208 d2 = (Int_t)(TMath::Abs(px2 - px) + TMath::Abs(py2 - py)) ;
209 px3 = gPad->XtoAbsPixel(-1);
210 py3 = gPad->YtoAbsPixel(-1);
211 d3 = TMath::Abs(px3 - px) + TMath::Abs(py3 - py) ; //simply take sum of pixels differences
212 // check if point is close to the radial axis
213 if (d1 < kMaxDiff) {
214 gPad->SetCursor(kMove);
215 p1 = kTRUE;
216 }
217 // check if point is close to the left high axis
218 if ( d2 < kMaxDiff) {
219 gPad->SetCursor(kHand);
220 p7 = kTRUE;
221 }
222 // check if point is close to the left down axis
223 if ( d3 < kMaxDiff) {
224 gPad->SetCursor(kHand);
225 p8 = kTRUE;
226 }
227 // check if point is close to a main circle
228 if (!p1 && !p7 ) {
229 p6 = kTRUE;
230 gPad->SetCursor(kHand);
231 }
232 break;
233
234 case kButton1Down:
235 // Record initial coordinates
236 //px4 = px;
237 //py4 = py;
238
239 case kButton1Motion:
240 if (p1) {
241 px2 = gPad->AbsPixeltoX(px);
242 py2 = gPad->AbsPixeltoY(py);
243 if ( px2 < 0 && py2 < 0) {p2 = kTRUE;};
244 if ( px2 < 0 && py2 > 0 ) {p3 = kTRUE;};
245 if ( px2 > 0 && py2 > 0 ) {p4 = kTRUE;};
246 if ( px2 > 0 && py2 < 0 ) {p5 = kTRUE;};
247 px2 = TMath::ACos(TMath::Abs(px2));
248 py2 = TMath::ASin(TMath::Abs(py2));
249 if (p2) {
250 fAxisAngle = TMath::Pi()+(px2+py2)/2;
251 p2 = kFALSE;
252 };
253 if (p3) {
254 fAxisAngle = TMath::Pi()-(px2+py2)/2;
255 p3 = kFALSE;
256 };
257 if (p4) {
258 fAxisAngle = (px2+py2)/2;
259 p4 = kFALSE;
260 };
261 if (p5) {
262 fAxisAngle = -(px2+py2)/2;
263 p5 = kFALSE;
264 };
265 }
266 break;
267
268 case kButton1Up:
269 Paint();
270 }
271}
272
273////////////////////////////////////////////////////////////////////////////////
274/// Find the alignement rule to apply for TText::SetTextAlign(Short_t).
275
277{
279
280 while(angle < 0 || angle > 2*pi){
281 if(angle < 0) angle+=2*pi;
282 if(angle > 2*pi) angle-=2*pi;
283 }
285 if(angle > 0 && angle < pi/2) return 11;
286 else if(angle > pi/2 && angle < pi) return 31;
287 else if(angle > pi && angle < 3*pi/2) return 33;
288 else if(angle > 3*pi/2 && angle < 2*pi) return 13;
289 else if(angle == 0 || angle == 2*pi) return 12;
290 else if(angle == pi/2) return 21;
291 else if(angle == pi) return 32;
292 else if(angle == 3*pi/2) return 23;
293 else return 0;
294 }
295 else{
296 if(angle >= 0 && angle <= pi/2) return 12;
297 else if((angle > pi/2 && angle <= pi) || (angle > pi && angle <= 3*pi/2)) return 32;
298 else if(angle > 3*pi/2 && angle <= 2*pi) return 12;
299 else return 0;
300 }
301}
302
303////////////////////////////////////////////////////////////////////////////////
304/// Determine the orientation of the polar labels according to their angle.
305
307{
309 Double_t convraddeg = 180.0/pi;
310
311 while(angle < 0 || angle > 2*pi){
312 if(angle < 0) angle+=2*pi;
313 if(angle > 2*pi) angle-=2*pi;
314 }
315
316 if(angle >= 0 && angle <= pi/2) return angle*convraddeg;
317 else if(angle > pi/2 && angle <= pi) return (angle + pi)*convraddeg;
318 else if(angle > pi && angle <= 3*pi/2) return (angle - pi)*convraddeg;
319 else if(angle > 3*pi/2 && angle <= 2*pi) return angle*convraddeg;
320 else return 0;
321}
322
323////////////////////////////////////////////////////////////////////////////////
324/// Initialize some of the fields of TGraphPolargram.
325
327{
328 fAxisAngle = 0;
329 fCutRadial = 0;
330 fDegree = kFALSE;
331 fGrad = kFALSE;
332 fLineStyle = 3;
334 fPolarLabelFont = 62;
335 fPolarOffset = 0.04;
336 fPolarTextSize = 0.04;
337 fRadialOffset = 0.025;
338 fRadian = kTRUE;
340 fRadialLabelFont = 62;
341 fRadialTextSize = 0.035;
342 fTickpolarSize = 0.02;
343}
344
345////////////////////////////////////////////////////////////////////////////////
346/// Paint TGraphPolargram.
347
349{
350 Int_t optionpoldiv, optionraddiv;
351 Bool_t optionLabels = kTRUE;
352
353 TString opt = chopt;
354 opt.ToUpper();
355
356 if(opt.Contains('P')) optionpoldiv=1; else optionpoldiv=0;
357 if(opt.Contains('R')) optionraddiv=1; else optionraddiv=0;
360 if(!opt.Contains('P') && !opt.Contains('R')) optionpoldiv=optionraddiv=1;
361 if(opt.Contains('N')) optionLabels = kFALSE;
362
363 if(optionraddiv) PaintRadialDivisions(kTRUE);
365 if(optionpoldiv) PaintPolarDivisions(optionLabels);
366}
367
368////////////////////////////////////////////////////////////////////////////////
369/// This is simplified from TEllipse::PaintEllipse.
370/// Draw this ellipse with new coordinates.
371
373 Double_t phimin, Double_t phimax, Double_t theta)
374{
375 Int_t i;
376 const Int_t np = 200; // Number of point to draw circle
377 static Double_t x[np+3], y[np+3];
378
379 // Set number of points approximatively proportional to the ellipse
380 // circumference.
381
382 Double_t circ = TMath::Pi()*2*r*(phimax-phimin)/36;
383 Int_t n = (Int_t)(np*circ/((gPad->GetX2()-gPad->GetX1())+
384 (gPad->GetY2()-gPad->GetY1())));
385 if (n < 8) n = 8;
386 if (n > np) n = np;
387 Double_t angle,dx,dy;
388 Double_t dphi = (phimax-phimin)*TMath::Pi()/(180*n);
389 Double_t ct = TMath::Cos(TMath::Pi()*theta/180);
390 Double_t st = TMath::Sin(TMath::Pi()*theta/180);
391 for (i=0; i<=n; i++) {
392 angle = phimin*TMath::Pi()/180 + Double_t(i)*dphi;
393 dx = r*TMath::Cos(angle);
394 dy = r*TMath::Sin(angle);
395 x[i] = x1 + dx*ct - dy*st;
396 y[i] = y1 + dx*st + dy*ct;
397 }
398 gPad->PaintPolyLine(n+1,x,y);
399}
400
401////////////////////////////////////////////////////////////////////////////////
402/// Draw Polar divisions.
403/// Check for editable pad or create default.
404
406{
407 Int_t i, j, rnum, rden, first, last;
408 if (!gPad) return ;
409
410 gPad->RangeAxis(-1,-1,1,1);
411 gPad->Range(-1.25,-1.25,1.25,1.25);
412 Int_t ndivMajor = fNdivPol%100;
413 Int_t ndivMinor = fNdivPol/100;
414
415 if (!gPad->GetLogy()) {
416 for (i=0; i<ndivMajor; i++) {
417 Double_t txtval = fRwtmin + i*(fRwtmax-fRwtmin)/ndivMajor;
418 Double_t theta = i*2*TMath::Pi()/ndivMajor;
419 Double_t costheta = TMath::Cos(theta);
420 Double_t sintheta = TMath::Sin(theta);
421 Double_t tantheta = TMath::Tan(theta);
422 Double_t costhetas = (1+fPolarOffset)*costheta;
423 Double_t sinthetas = (1+fPolarOffset)*sintheta;
424 Double_t corr = 0.01;
425
426 TLatex textangular;
427 textangular.SetTextColor(GetPolarColorLabel());
428 textangular.SetTextFont(GetPolarLabelFont());
429
430 TString form = " ";
431 TGaxis axis;
433 // Polar numbers are aligned with their axis.
434 if(!fPolarLabels && optionLabels){;
435 if (fRadian) {
436 // Radian case.
437 ReduceFraction(2*i, ndivMajor, rnum, rden); // Reduces the fraction.
438 if (rnum == 0) form.Form("%d",rnum);
439 if (rnum == 1 && rden == 1) form = "#pi";
440 if (rnum == 1 && rden != 1) form.Form("#frac{#pi}{%d}",rden);
441 if (rnum != 1 && rden == 1 && i !=0) form.Form("%d#pi",rnum);
442 if (rnum != 1 && rden != 1) form.Form("#frac{%d#pi}{%d}",rnum,rden);
443 textangular.SetTextAlign(FindAlign(theta));
444 textangular.PaintLatex(costhetas,
445 sinthetas, FindTextAngle(theta),
446 GetPolarLabelSize(), form.Data());
447 } else {
448 // Any other cases: numbers are aligned with their axis.
449 form.Form("%5.3g",txtval);
450 axis.LabelsLimits(form.Data(),first,last);
451 TString s = form;
452 if (first != 0) s.Remove(0, first);
453 textangular.SetTextAlign(FindAlign(theta));
454 textangular.PaintLatex(costhetas,
455 sinthetas, FindTextAngle(theta),
457 }
458 } else if (fPolarLabels){
459 // print the specified polar labels
460 textangular.SetTextAlign(FindAlign(theta));
461 textangular.PaintLatex(costhetas,sinthetas,FindTextAngle(theta),
463 }
464 } else {
465 // Polar numbers are shown horizontally.
466 if(!fPolarLabels && optionLabels){
467 if (fRadian) {
468 // Radian case
469 ReduceFraction(2*i, ndivMajor, rnum, rden);
470 if (rnum == 0) form.Form("%d",rnum);
471 if (rnum == 1 && rden == 1) form = "#pi";
472 if (rnum == 1 && rden != 1) form.Form("#frac{#pi}{%d}",rden);
473 if (rnum != 1 && rden == 1 && i !=0) form.Form("%d#pi",rnum);
474 if (rnum != 1 && rden != 1) form.Form("#frac{%d#pi}{%d}",rnum,rden);
475 if(theta >= 3*TMath::Pi()/12.0 && theta < 2*TMath::Pi()/3.0) corr=0.04;
476 textangular.SetTextAlign(FindAlign(theta));
477 textangular.PaintLatex(costhetas,corr+sinthetas,0,
478 GetPolarLabelSize(),form.Data());
479 } else {
480 // Any other cases where numbers are shown horizontally.
481 form.Form("%5.3g",txtval);
482 axis.LabelsLimits(form.Data(),first,last);
483 TString s = form;
484 if (first != 0) s.Remove(0, first);
485 if(theta >= 3*TMath::Pi()/12.0 && theta < 2*TMath::Pi()/3.0) corr=0.04;
486 textangular.SetTextAlign(FindAlign(theta));
487 textangular.PaintLatex(costhetas, //j'ai efface des offset la
488 corr+sinthetas,0,GetPolarLabelSize(),s);
489 }
490 } else if (fPolarLabels) {
491 // print the specified polar labels
492 textangular.SetTextAlign(FindAlign(theta));
493 textangular.PaintText(costhetas,sinthetas,fPolarLabels[i]);
494 }
495 }
497 //Check if SetTickPolar is activated, and draw tick marks
498 Bool_t issettickpolar = gPad->GetTicky();
499
500 if (issettickpolar) {
501 if (theta != 0 && theta !=TMath::Pi()) {
502 gPad->PaintLine((sintheta-GetTickpolarSize())/tantheta,sintheta-GetTickpolarSize(),
503 (sintheta+GetTickpolarSize())/tantheta,sintheta+GetTickpolarSize());
504 }
505 if (theta == 0 || theta ==TMath::Pi()) {
506 gPad->PaintLine(1-GetTickpolarSize(),0,1+GetTickpolarSize(),0);
507 gPad->PaintLine(-1+GetTickpolarSize(),0,-1-GetTickpolarSize(),0);
508 }
509 }
512 gPad->PaintLine(0.,0.,costheta,sintheta);
513 // Add minor lines w/o text.
514 Int_t oldLineStyle = GetLineStyle();
515 TAttLine::SetLineStyle(2); //Minor lines always in this style.
516 TAttLine::Modify(); //Changes line attributes apart from style.
517 for (j=1; j<ndivMinor; j++) {
518 Double_t thetamin = theta+j*2*TMath::Pi()/(ndivMajor*ndivMinor);
519 gPad->PaintLine(0.,0.,TMath::Cos(thetamin),TMath::Sin(thetamin));
520 }
521 TAttLine::SetLineStyle(oldLineStyle);
523 }
524 } else {
525 Int_t big = (Int_t)fRwtmax;
526 Int_t test= 1;
527 while (big >= 10) {
528 big = big/10;
529 test++;
530 }
531 for (i=1; i<=test; i++) {
532 Double_t txtval = pow((double)10,(double)(i-1));
533 Double_t theta = (i-1)*2*TMath::Pi()/(double)(test);
534 Double_t costheta = TMath::Cos(theta);
535 Double_t sintheta = TMath::Sin(theta);
536 Double_t tantheta = TMath::Tan(theta);
537 Double_t costhetas = (1+fPolarOffset)*costheta;
538 Double_t sinthetas = (1+fPolarOffset)*sintheta;
539 Double_t corr = 0.01;
540
541 TLatex textangular;
542 textangular.SetTextColor(GetPolarColorLabel());
543 textangular.SetTextFont(GetPolarLabelFont());
544
545 TString form = " ";
546 TGaxis axis;
547
549 if(!fPolarLabels && optionLabels){
550 // Polar numbers are aligned with their axis.
551 form.Form("%5.3g",txtval);
552 axis.LabelsLimits(form.Data(),first,last);
553 TString s = form;
554 if (first != 0) s.Remove(0, first);
555 textangular.SetTextAlign(FindAlign(theta));
556 textangular.PaintLatex(costhetas,
557 sinthetas, FindTextAngle(theta), GetPolarLabelSize(), s);
558 }
559 else if (fPolarLabels){
560 // print the specified polar labels
561 textangular.SetTextAlign(FindAlign(theta));
562 textangular.PaintText(costhetas,sinthetas,fPolarLabels[i]);
563 }
564
565 } else {
566 if(!fPolarLabels && optionLabels){
567 // Polar numbers are shown horizontally.
568 form.Form("%5.3g",txtval);
569 axis.LabelsLimits(form.Data(),first,last);
570 TString s = form;
571 if (first != 0) s.Remove(0, first);
572 if(theta >= 3*TMath::Pi()/12.0 && theta < 2*TMath::Pi()/3.0) corr=0.04;
573 textangular.SetTextAlign(FindAlign(theta));
574 textangular.PaintLatex(costhetas,
575 corr+sinthetas,0,GetPolarLabelSize(),s);
576 } else if (fPolarLabels){
577 // print the specified polar labels
578 textangular.SetTextAlign(FindAlign(theta));
579 textangular.PaintText(costhetas,sinthetas,fPolarLabels[i]);
580 }
581 }
582
584 //Check if SetTickPolar is activated, and draw tick marks
585 Bool_t issettickpolar = gPad->GetTicky();
586 if (issettickpolar) {
587 if (theta != 0 && theta !=TMath::Pi()) {
588 gPad->PaintLine((sintheta-GetTickpolarSize())/tantheta,sintheta-GetTickpolarSize(),
589 (sintheta+GetTickpolarSize())/tantheta,sintheta+GetTickpolarSize());
590 }
591 if (theta == 0 || theta ==TMath::Pi()) {
592 gPad->PaintLine(1-GetTickpolarSize(),0,1+GetTickpolarSize(),0);
593 gPad->PaintLine(-1+GetTickpolarSize(),0,-1-GetTickpolarSize(),0);
594 }
595 }
598 gPad->PaintLine(0.,0.,costheta,sintheta);
599 // Add minor lines w/o text.
600 Int_t oldLineStyle = GetLineStyle();
601 TAttLine::SetLineStyle(2); //Minor lines always in this style.
602 TAttLine::Modify(); //Changes line attributes apart from style.
603 Double_t a=0;
604 Double_t b,c,d;
605 b = TMath::Log(10)*test;
606 d= 2*TMath::Pi()/(double)test;
607 for (j=1; j<9; j++) {
608 a=TMath::Log(j+1)-TMath::Log(j)+a;
609 c=a/b*6.28+d*(i-1);
610 gPad->PaintLine(0.,0.,TMath::Cos(c),TMath::Sin(c));
611 }
612 TAttLine::SetLineStyle(oldLineStyle);
614 }
615 }
616}
617
618////////////////////////////////////////////////////////////////////////////////
619/// Paint radial divisions.
620/// Check for editable pad or create default.
621
623{
624 static char chopt[8] = "";
625 Int_t i,j;
626 Int_t ndiv = TMath::Abs(fNdivRad);
627 Int_t ndivMajor = ndiv%100;
628 Int_t ndivMinor = ndiv/100;
629 Int_t ndivmajor = 0;
630 Double_t frwrmin = 0., frwrmax = 0., binWidth = 0;
631
632 THLimitsFinder::Optimize(fRwrmin,fRwrmax,ndivMajor,frwrmin,
633 frwrmax, ndivmajor,binWidth,"");
634
635 if (!gPad) return ;
636 if (!gPad->GetLogx()) {
637 gPad->RangeAxis(-1,-1,1,1);
638 gPad->Range(-1.25,-1.25,1.25,1.25);
639 Double_t umin = fRwrmin;
640 Double_t umax = fRwrmax;
641 Double_t rmajmin = (frwrmin-fRwrmin)/(fRwrmax-fRwrmin);
642 Double_t rmajmax = (frwrmax-fRwrmin)/(fRwrmax-fRwrmin);
643 Double_t dist = (rmajmax-rmajmin)/ndivmajor;
644 Int_t ndivminor = 0;
645
646 chopt[0] = 0;
647 strncat(chopt, "SDH", 4);
648 if (fNdivRad < 0) strncat(chopt, "N",2);
649 if(drawaxis){
650 // Paint axis.
651 TGaxis axis;
657 umin, umax, ndiv, chopt, 0., kFALSE);
658 }
659
660 // Paint Circles.
661 // First paint main circle.
662 PaintCircle(0.,0.,1,0.,360,0);
663 // Optimised case.
664 if (fNdivRad>0 ) {
665 Double_t frwrmini = 0., frwrmaxi = 0., binWidth2 =0;
666 THLimitsFinder::Optimize(frwrmin,frwrmin+binWidth,ndivMinor,frwrmini,
667 frwrmaxi, ndivminor,binWidth2,"");
668 Double_t dist2 = dist/(ndivminor);
669 // Paint major circles.
670 for (i=1; i<=ndivmajor+2; i++) {
673 PaintCircle(0.,0.,rmajmin,0.,360,0);
674
675 //Paint minor circles.
678 for (j=1; j<ndivminor+1; j++) {
679 if (rmajmin+j*dist2<=1) PaintCircle(0.,0.,rmajmin+j*dist2,0.,360,0);
680 }
681 rmajmin = (frwrmin-fRwrmin)/(fRwrmax-fRwrmin)+(i-1)*dist;
682 }
683 // Non-optimized case.
684 } else {
685
686 // Paint major circles.
687 for (i=1; i<=ndivMajor; i++) {
690 Double_t rmaj = i*1./ndivMajor;
691 PaintCircle(0.,0.,rmaj,0.,360,0);
692
693 // Paint minor circles.
694 for (j=1; j<ndivMinor; j++) {
697 PaintCircle(0.,0.,rmaj- j*1./(ndivMajor*ndivMinor),0.,360,0);
698 }
699 }
700 }
701 } else {
702 // Draw Log scale on radial axis if option activated.
703 Int_t big = (Int_t)fRwrmax;
704 Int_t test= 0;
705 while (big >= 10) {
706 big = big/10;
707 test++;
708 }
709 for (i=1; i<=test; i++) {
712 Double_t ecart;
713 ecart = ((double) i)/ ((double) test);
714 PaintCircle(0.,0.,ecart,0,360,0);
717 Double_t a=0;
718 Double_t b,c,d;
719 b = TMath::Log(10)*test;
720 d = 1/(double)test;
721 for (j=1; j<9; j++) {
722 a = TMath::Log(j+1)-TMath::Log(j)+a;
723 c = a/b+d*(i-1);
724 PaintCircle(0,0.,c,0.,360,0);
725 }
726 }
727 }
730}
731
732////////////////////////////////////////////////////////////////////////////////
733/// Reduce fractions.
734
736{
737 Int_t a = 0;
738 Int_t b = 0;
739 Int_t i = 0;
740 Int_t j = 0;
741 a = den;
742 b = num;
743 if (b > a) {
744 j = b;
745 } else {
746 j = a;
747 }
748 for (i=j; i > 1; i--) {
749 if ((a % i == 0) && (b % i == 0)) {
750 a = a/i;
751 b = b/i;
752 }
753 }
754 rden = a;
755 rnum = b;
756}
757
758////////////////////////////////////////////////////////////////////////////////
759/// Set axis angle.
760
762{
763 fAxisAngle = angle/180*TMath::Pi();
764}
765
766////////////////////////////////////////////////////////////////////////////////
767/// Set the number of Polar divisions: enter a number ij with 0<i<99 and 0<j<99
768/// - i sets the major Polar divisions.
769/// - j sets the minor Polar divisions.
770
772{
773 if (ndiv > 0)
774 fNdivPol = ndiv;
775 if (gPad) gPad->Modified();
776}
777
778////////////////////////////////////////////////////////////////////////////////
779/// Set the number of radial divisions: enter a number ij with 0<i<99 and 0<j<99
780/// - i sets the major radial divisions.
781/// - j sets the minor radial divisions.
782
784{
785 fNdivRad = ndiv;
786 if (gPad) gPad->Modified();
787}
788
789////////////////////////////////////////////////////////////////////////////////
790/// Set some specified polar labels, used in the case of a spider plot.
791
793{
794 if(!fPolarLabels)
796 fPolarLabels[div] = label;
797 if (gPad) gPad->Modified();
798}
799
800////////////////////////////////////////////////////////////////////////////////
801/// Set Polar labels color.
802
804{
805 fPolarLabelColor = tcolorangular;
806}
807
808////////////////////////////////////////////////////////////////////////////////
809
811{
812 // Set Polar label font.
813
814 fPolarLabelFont = tfontangular;
815}
816
817////////////////////////////////////////////////////////////////////////////////
818/// Set angular labels size.
819
821{
822 fPolarTextSize = angularsize;
823}
824
825////////////////////////////////////////////////////////////////////////////////
826/// Set the labels offset.
827
829{
830 fPolarOffset = angularOffset;
831 if (gPad) gPad->Modified();
832}
833
834////////////////////////////////////////////////////////////////////////////////
835/// Set radial labels color.
836
838{
839 fRadialLabelColor = tcolorradial;
840}
841
842////////////////////////////////////////////////////////////////////////////////
843/// Set radial label font.
844
846{
847 fRadialLabelFont = tfontradial;
848}
849
850////////////////////////////////////////////////////////////////////////////////
851/// Set radial labels size.
852
854{
855 fRadialTextSize = radialsize;
856}
857
858////////////////////////////////////////////////////////////////////////////////
859/// Set the labels offset.
860
862{
863 fRadialOffset = radialOffset;
864 if (gPad) gPad->Modified();
865}
866
867////////////////////////////////////////////////////////////////////////////////
868/// Allows to change range Polar.
869/// \param[in] tmin the start number.
870/// \param[in] tmax the end number.
871
873{
874 fDegree = kFALSE;
875 fGrad = kFALSE;
876 fRadian = kFALSE;
877
878 if (tmin < tmax) {
879 fRwtmin = tmin;
880 fRwtmax = tmax;
881 }
882 if (gPad) gPad->Modified();
883}
884
885////////////////////////////////////////////////////////////////////////////////
886/// Set the radial range.
887/// \param[in] rmin radius at center of the circle.
888/// \param[in] rmax radius at the intersection of the right X axis part and the circle.
889
891{
892 if (rmin < rmax) {
893 fRwrmin = rmin;
894 fRwrmax = rmax;
895 }
896 if (gPad) gPad->Modified();
897}
898
899////////////////////////////////////////////////////////////////////////////////
900/// Set polar ticks size.
901
903{
904 fTickpolarSize = tickpolarsize;
905}
906
907////////////////////////////////////////////////////////////////////////////////
908/// The Polar circle is labelled using degree.
909
911{
912 fDegree = kTRUE;
913 fGrad = kFALSE;
914 fRadian = kFALSE;
915 ChangeRangePolar(0,360);
916}
917
918////////////////////////////////////////////////////////////////////////////////
919/// The Polar circle is labelled using gradian.
920
922{
923 fGrad = kTRUE;
924 fRadian = kFALSE;
925 fDegree = kFALSE;
926 ChangeRangePolar(0,200);
927}
928
929////////////////////////////////////////////////////////////////////////////////
930/// The Polar circle is labelled using radian.
931
933{
934 fRadian = kTRUE;
935 fGrad = kFALSE;
936 fDegree = kFALSE;
938}
939
940////////////////////////////////////////////////////////////////////////////////
941/// Set range from 0 to 2*pi
942
944{
946}
@ kMouseMotion
Definition: Buttons.h:23
@ kButton1Motion
Definition: Buttons.h:20
@ kButton1Up
Definition: Buttons.h:19
@ kButton1Down
Definition: Buttons.h:17
@ kMove
Definition: GuiTypes.h:374
@ kHand
Definition: GuiTypes.h:374
const Int_t kMaxPixel
Max value for an int.
Definition: GuiTypes.h:369
#define d(i)
Definition: RSha256.hxx:102
#define c(i)
Definition: RSha256.hxx:101
int Int_t
Definition: RtypesCore.h:45
short Color_t
Definition: RtypesCore.h:92
const Bool_t kFALSE
Definition: RtypesCore.h:101
short Font_t
Definition: RtypesCore.h:88
double Double_t
Definition: RtypesCore.h:59
const Bool_t kTRUE
Definition: RtypesCore.h:100
const char Option_t
Definition: RtypesCore.h:66
#define ClassImp(name)
Definition: Rtypes.h:375
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t b
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t np
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint TPoint angle
Option_t Option_t TPoint TPoint const char y1
char name[80]
Definition: TGX11.cxx:110
#define gPad
Definition: TVirtualPad.h:288
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition: TAttLine.h:42
virtual Style_t GetLineStyle() const
Return the line style.
Definition: TAttLine.h:34
virtual void Modify()
Change current line attributes if necessary.
Definition: TAttLine.cxx:245
Style_t fLineStyle
Line style.
Definition: TAttLine.h:22
Int_t DistancetoLine(Int_t px, Int_t py, Double_t xp1, Double_t yp1, Double_t xp2, Double_t yp2)
Compute distance from point px,py to a line.
Definition: TAttLine.cxx:209
virtual void SetTextAlign(Short_t align=11)
Set the text alignment.
Definition: TAttText.h:42
virtual void SetTextColor(Color_t tcolor=1)
Set the text color.
Definition: TAttText.h:44
virtual void SetTextFont(Font_t tfont=62)
Set the text font.
Definition: TAttText.h:46
The axis painter class.
Definition: TGaxis.h:23
virtual void PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax, Double_t &wmin, Double_t &wmax, Int_t &ndiv, Option_t *chopt="", Double_t gridlength=0, Bool_t drawGridOnly=kFALSE)
Control function to draw an axis.
Definition: TGaxis.cxx:1013
void SetLabelFont(Int_t labelfont)
Definition: TGaxis.h:108
void SetLabelOffset(Float_t labeloffset)
Definition: TGaxis.h:109
void SetLabelColor(Int_t labelcolor)
Definition: TGaxis.h:107
void SetLabelSize(Float_t labelsize)
Definition: TGaxis.h:110
void LabelsLimits(const char *label, Int_t &first, Int_t &last)
Internal method to find first and last character of a label.
Definition: TGaxis.cxx:2528
To draw polar axis.
Double_t fRwrmin
Minimal radial value (real world)
void ReduceFraction(Int_t Num, Int_t Denom, Int_t &rnum, Int_t &rden)
Reduce fractions.
Double_t GetPolarLabelSize()
Color_t fRadialLabelColor
Set color of the radial labels.
void SetPolarLabelColor(Color_t tcolorangular=1)
Set Polar labels color.
void PaintPolarDivisions(Bool_t noLabels)
Draw Polar divisions.
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
Everything within the circle belongs to the TGraphPolargram.
void SetRangePolar(Double_t tmin, Double_t tmax)
Allows to change range Polar.
Double_t fPolarTextSize
Set Polar text size.
Double_t fRwtmin
Minimal angular value (real world)
Double_t GetRadialOffset()
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
Indicate that there is something to click here.
void Init()
Initialize some of the fields of TGraphPolargram.
Double_t fRadialTextSize
Double_t GetTickpolarSize()
void SetPolarOffset(Double_t PolarOffset=0.04)
Set the labels offset.
void SetTwoPi()
Set range from 0 to 2*pi.
Double_t FindTextAngle(Double_t theta)
Determine the orientation of the polar labels according to their angle.
void SetRadialLabelColor(Color_t tcolorradial=1)
Set radial labels color.
void PaintCircle(Double_t x, Double_t y, Double_t r, Double_t phimin, Double_t phimax, Double_t theta)
This is simplified from TEllipse::PaintEllipse.
virtual ~TGraphPolargram()
TGraphPolargram destructor.
void SetRangeRadial(Double_t rmin, Double_t rmax)
Set the radial range.
void SetTickpolarSize(Double_t tickpolarsize=0.02)
Set polar ticks size.
void SetAxisAngle(Double_t angle=0)
Set axis angle.
void SetToDegree()
The Polar circle is labelled using degree.
void SetNdivPolar(Int_t Ndiv=508)
Set the number of Polar divisions: enter a number ij with 0<i<99 and 0<j<99.
Int_t fNdivRad
Number of radial divisions.
Font_t GetPolarLabelFont()
void Draw(Option_t *options="") override
Draw Polargram.
Double_t fTickpolarSize
Set size of Tickmarks.
void SetRadialLabelSize(Double_t radialsize=0.035)
Set radial labels size.
Font_t fPolarLabelFont
Set font of angular labels.
TString * fPolarLabels
! [fNdivPol] Specified polar labels
void PaintRadialDivisions(Bool_t drawaxis)
Paint radial divisions.
void SetToGrad()
The Polar circle is labelled using gradian.
Double_t GetAngle()
void ChangeRangePolar(Double_t tmin, Double_t tmax)
Set the Polar range.
void SetPolarLabelSize(Double_t angularsize=0.04)
Set angular labels size.
void SetRadialLabelFont(Font_t tfontradial=62)
Set radial label font.
Double_t fAxisAngle
Set angle of the radial axis.
void SetToRadian()
The Polar circle is labelled using radian.
Double_t fRwtmax
Minimal angular value (real world)
Double_t fRwrmax
Maximal radial value (real world)
void SetPolarLabel(Int_t div, const TString &label)
Set some specified polar labels, used in the case of a spider plot.
TGraphPolargram(const char *name, Double_t rmin, Double_t rmax, Double_t tmin, Double_t tmax)
TGraphPolargram Constructor.
Font_t fRadialLabelFont
Set font of radial labels.
Int_t fNdivPol
Number of polar divisions.
Font_t GetRadialLabelFont()
Int_t fCutRadial
if fCutRadial = 0, circles are cut by radial axis if fCutRadial = 1, circles are not cut
Color_t fPolarLabelColor
Set color of the angular labels.
Double_t fPolarOffset
Offset for Polar labels.
void Paint(Option_t *options="") override
Paint TGraphPolargram.
void SetPolarLabelFont(Font_t tfontangular=62)
void SetRadialOffset(Double_t RadialOffset=0.025)
Set the labels offset.
Color_t GetRadialColorLabel()
Int_t FindAlign(Double_t angle)
Find the alignement rule to apply for TText::SetTextAlign(Short_t).
void SetNdivRadial(Int_t Ndiv=508)
Set the number of radial divisions: enter a number ij with 0<i<99 and 0<j<99.
Double_t GetRadialLabelSize()
Color_t GetPolarColorLabel()
Double_t fRadialOffset
Offset for radial labels.
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.
To draw Mathematical Formula.
Definition: TLatex.h:18
virtual void PaintLatex(Double_t x, Double_t y, Double_t angle, Double_t size, const char *text)
Main drawing function.
Definition: TLatex.cxx:2053
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:201
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition: TObject.cxx:184
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:775
void ResetBit(UInt_t f)
Definition: TObject.h:200
Basic string class.
Definition: TString.h:136
const char * Data() const
Definition: TString.h:369
void ToUpper()
Change string to upper case.
Definition: TString.cxx:1172
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2323
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:624
virtual void PaintText(Double_t x, Double_t y, const char *text)
Draw this text with new coordinates.
Definition: TText.cxx:744
RVec< PromoteTypes< T0, T1 > > pow(const T0 &x, const RVec< T1 > &v)
Definition: RVec.hxx:1792
Double_t y[n]
Definition: legend1.C:17
Double_t x[n]
Definition: legend1.C:17
const Int_t n
Definition: legend1.C:16
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
static constexpr double rad
static constexpr double s
static constexpr double pi
Double_t ACos(Double_t)
Returns the principal value of the arc cosine of x, expressed in radians.
Definition: TMath.h:630
Double_t ASin(Double_t)
Returns the principal value of the arc sine of x, expressed in radians.
Definition: TMath.h:622
constexpr Double_t PiOver2()
Definition: TMath.h:51
Double_t Log(Double_t x)
Returns the natural logarithm of x.
Definition: TMath.h:754
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition: TMath.h:660
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
Definition: TMath.h:719
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
Double_t Tan(Double_t)
Returns the tangent of an angle of x radians.
Definition: TMath.h:598
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition: TMathBase.h:123
Definition: first.py:1
Definition: test.py:1
TArc a
Definition: textangle.C:12