53 ClassImp(TGraphPolargram);
58 TGraphPolargram::TGraphPolargram(
const char* name, Double_t rmin, Double_t rmax,
59 Double_t tmin, Double_t tmax):
60 TNamed(name,
"Polargram")
75 TGraphPolargram::TGraphPolargram(
const char* name):
76 TNamed(name,
"Polargram")
91 TGraphPolargram::~TGraphPolargram()
93 if (fPolarLabels != NULL)
delete [] fPolarLabels;
101 void TGraphPolargram::ChangeRangePolar(Double_t tmin, Double_t tmax)
107 if (gPad) gPad->Modified();
113 Int_t TGraphPolargram::DistancetoPrimitive(Int_t px, Int_t py)
116 Double_t x = gPad->AbsPixeltoX(px);
117 Double_t y = gPad->AbsPixeltoY(py);
120 Double_t rad = TMath::Sqrt(x*x+y*y);
121 Int_t div = (Int_t)rad*(fNdivRad%100);
122 Double_t dr = TMath::Min(TMath::Abs(rad-div*1./(fNdivRad%100)),
123 TMath::Abs(rad-(div+1)*1./(fNdivRad%100)));
124 Int_t drad = gPad->XtoPixel(dr)-gPad->XtoPixel(0);
128 Int_t dt = kMaxPixel;
129 for (i=0; i<(fNdivPol%100); i++) {
130 Double_t theta = i*2*TMath::Pi()/(fNdivPol%100);
133 Int_t dthis = DistancetoLine(px,py,0.,0.,TMath::Cos(theta),
142 dthis = (Int_t)TMath::Sqrt(
143 TMath::Power(px-gPad->XtoPixel(TMath::Cos(theta)),2)+
144 TMath::Power(py-gPad->YtoPixel(TMath::Sin(theta)),2));
148 if (((TMath::Abs(theta-TMath::Pi())<0.1) &&
149 ((px-gPad->XtoPixel(0))<0)) ||
150 ((TMath::Abs(theta)<0.1) &&
151 ((px-gPad->XtoPixel(0))>0))) {
152 dthis = TMath::Abs(py-gPad->YtoPixel(0.));
156 if (((TMath::Abs(theta-TMath::PiOver2())<0.1) &&
157 ((py-gPad->YtoPixel(0))>0)) ||
158 ((TMath::Abs(theta-3*TMath::PiOver2())<0.1) &&
159 (py-gPad->YtoPixel(0))<0)) {
160 dthis = TMath::Abs(px-gPad->XtoPixel(0.));
166 dthis = (Int_t)TMath::Sqrt(
167 TMath::Power(px-gPad->XtoPixel(0.),2)+
168 TMath::Power(py-gPad->YtoPixel(0.),2));
174 dt = TMath::Min(dthis,dt);
176 return TMath::Min(drad, dt);
182 void TGraphPolargram::Draw(Option_t* options)
191 void TGraphPolargram::ExecuteEvent(Int_t event, Int_t px, Int_t py)
196 static Int_t d1, d2, d3, px1, py1, px3, py3;
197 static Bool_t p1, p2, p3, p4, p5, p6, p7, p8;
199 p2 = p3 = p4 = p5 = p6 = p7 = p8 = kFALSE;
200 if (!gPad->IsEditable())
return;
203 px1 = gPad->XtoAbsPixel(TMath::Cos(GetAngle()));
204 py1 = gPad->YtoAbsPixel(TMath::Sin(GetAngle()));
205 d1 = TMath::Abs(px1 - px) + TMath::Abs(py1-py);
207 px2 = gPad->XtoAbsPixel(-1);
208 py2 = gPad->YtoAbsPixel(1);
209 d2 = (Int_t)(TMath::Abs(px2 - px) + TMath::Abs(py2 - py)) ;
210 px3 = gPad->XtoAbsPixel(-1);
211 py3 = gPad->YtoAbsPixel(-1);
212 d3 = TMath::Abs(px3 - px) + TMath::Abs(py3 - py) ;
215 gPad->SetCursor(kMove);
219 if ( d2 < kMaxDiff) {
220 gPad->SetCursor(kHand);
224 if ( d3 < kMaxDiff) {
225 gPad->SetCursor(kHand);
231 gPad->SetCursor(kHand);
242 px2 = gPad->AbsPixeltoX(px);
243 py2 = gPad->AbsPixeltoY(py);
244 if ( px2 < 0 && py2 < 0) {p2 = kTRUE;};
245 if ( px2 < 0 && py2 > 0 ) {p3 = kTRUE;};
246 if ( px2 > 0 && py2 > 0 ) {p4 = kTRUE;};
247 if ( px2 > 0 && py2 < 0 ) {p5 = kTRUE;};
248 px2 = TMath::ACos(TMath::Abs(px2));
249 py2 = TMath::ASin(TMath::Abs(py2));
251 fAxisAngle = TMath::Pi()+(px2+py2)/2;
255 fAxisAngle = TMath::Pi()-(px2+py2)/2;
259 fAxisAngle = (px2+py2)/2;
263 fAxisAngle = -(px2+py2)/2;
277 Int_t TGraphPolargram::FindAlign(Double_t angle)
279 Double_t pi = TMath::Pi();
281 while(angle < 0 || angle > 2*pi){
282 if(angle < 0) angle+=2*pi;
283 if(angle > 2*pi) angle-=2*pi;
285 if(!TestBit(TGraphPolargram::kLabelOrtho)){
286 if(angle > 0 && angle < pi/2)
return 11;
287 else if(angle > pi/2 && angle < pi)
return 31;
288 else if(angle > pi && angle < 3*pi/2)
return 33;
289 else if(angle > 3*pi/2 && angle < 2*pi)
return 13;
290 else if(angle == 0 || angle == 2*pi)
return 12;
291 else if(angle == pi/2)
return 21;
292 else if(angle == pi)
return 32;
293 else if(angle == 3*pi/2)
return 23;
297 if(angle >= 0 && angle <= pi/2)
return 12;
298 else if((angle > pi/2 && angle <= pi) || (angle > pi && angle <= 3*pi/2))
return 32;
299 else if(angle > 3*pi/2 && angle <= 2*pi)
return 12;
307 Double_t TGraphPolargram::FindTextAngle(Double_t angle)
309 Double_t pi = TMath::Pi();
310 Double_t convraddeg = 180.0/pi;
312 while(angle < 0 || angle > 2*pi){
313 if(angle < 0) angle+=2*pi;
314 if(angle > 2*pi) angle-=2*pi;
317 if(angle >= 0 && angle <= pi/2)
return angle*convraddeg;
318 else if(angle > pi/2 && angle <= pi)
return (angle + pi)*convraddeg;
319 else if(angle > pi && angle <= 3*pi/2)
return (angle - pi)*convraddeg;
320 else if(angle > 3*pi/2 && angle <= 2*pi)
return angle*convraddeg;
327 void TGraphPolargram::Init()
334 fPolarLabelColor = 1;
335 fPolarLabelFont = 62;
337 fPolarTextSize = 0.04;
338 fRadialOffset = 0.025;
340 fRadialLabelColor = 1;
341 fRadialLabelFont = 62;
342 fRadialTextSize = 0.035;
343 fTickpolarSize = 0.02;
349 void TGraphPolargram::Paint(Option_t * chopt)
351 Int_t optionpoldiv, optionraddiv;
352 Bool_t optionLabels = kTRUE;
357 if(opt.Contains(
'P')) optionpoldiv=1;
else optionpoldiv=0;
358 if(opt.Contains(
'R')) optionraddiv=1;
else optionraddiv=0;
359 if(opt.Contains(
'O')) SetBit(TGraphPolargram::kLabelOrtho);
360 else ResetBit(TGraphPolargram::kLabelOrtho);
361 if(!opt.Contains(
'P') && !opt.Contains(
'R')) optionpoldiv=optionraddiv=1;
362 if(opt.Contains(
'N')) optionLabels = kFALSE;
364 if(optionraddiv) PaintRadialDivisions(kTRUE);
365 else PaintRadialDivisions(kFALSE);
366 if(optionpoldiv) PaintPolarDivisions(optionLabels);
373 void TGraphPolargram::PaintCircle(Double_t x1, Double_t y1, Double_t r,
374 Double_t phimin, Double_t phimax, Double_t theta)
377 const Int_t np = 200;
378 static Double_t x[np+3], y[np+3];
383 Double_t circ = TMath::Pi()*2*r*(phimax-phimin)/36;
384 Int_t n = (Int_t)(np*circ/((gPad->GetX2()-gPad->GetX1())+
385 (gPad->GetY2()-gPad->GetY1())));
388 Double_t angle,dx,dy;
389 Double_t dphi = (phimax-phimin)*TMath::Pi()/(180*n);
390 Double_t ct = TMath::Cos(TMath::Pi()*theta/180);
391 Double_t st = TMath::Sin(TMath::Pi()*theta/180);
392 for (i=0; i<=n; i++) {
393 angle = phimin*TMath::Pi()/180 + Double_t(i)*dphi;
394 dx = r*TMath::Cos(angle);
395 dy = r*TMath::Sin(angle);
396 x[i] = x1 + dx*ct - dy*st;
397 y[i] = y1 + dx*st + dy*ct;
399 gPad->PaintPolyLine(n+1,x,y);
406 void TGraphPolargram::PaintPolarDivisions(Bool_t optionLabels)
408 Int_t i, j, rnum, rden, first, last;
411 gPad->RangeAxis(-1,-1,1,1);
412 gPad->Range(-1.25,-1.25,1.25,1.25);
413 Int_t ndivMajor = fNdivPol%100;
414 Int_t ndivMinor = fNdivPol/100;
416 if (!gPad->GetLogy()) {
417 for (i=0; i<ndivMajor; i++) {
418 Double_t txtval = fRwtmin + i*(fRwtmax-fRwtmin)/ndivMajor;
419 Double_t theta = i*2*TMath::Pi()/ndivMajor;
420 Double_t costheta = TMath::Cos(theta);
421 Double_t sintheta = TMath::Sin(theta);
422 Double_t tantheta = TMath::Tan(theta);
423 Double_t costhetas = (1+fPolarOffset)*costheta;
424 Double_t sinthetas = (1+fPolarOffset)*sintheta;
425 Double_t corr = 0.01;
427 TLatex *textangular =
new TLatex();
428 textangular->SetTextColor(GetPolarColorLabel());
429 textangular->SetTextFont(GetPolarLabelFont());
431 const char* form = (
char *)
" ";
433 if (TestBit(TGraphPolargram::kLabelOrtho)) {
435 if(fPolarLabels == NULL && optionLabels){;
438 ReduceFraction(2*i, ndivMajor, rnum, rden);
439 if (rnum == 0) form = Form(
"%d",rnum);
440 if (rnum == 1 && rden == 1) form = Form(
"#pi");
441 if (rnum == 1 && rden != 1) form = Form(
"#frac{#pi}{%d}",rden);
442 if (rnum != 1 && rden == 1 && i !=0) form= Form(
"%d#pi",rnum);
443 if (rnum != 1 && rden != 1) form = Form(
"#frac{%d#pi}{%d}",rnum,rden);
444 textangular->SetTextAlign(FindAlign(theta));
445 textangular->PaintLatex(costhetas,
446 sinthetas, FindTextAngle(theta),
447 GetPolarLabelSize(), form);
450 form = Form(
"%5.3g",txtval);
451 axis.LabelsLimits(form,first,last);
452 TString s = Form(
"%s",form);
453 if (first != 0) s.Remove(0, first);
454 textangular->SetTextAlign(FindAlign(theta));
455 textangular->PaintLatex(costhetas,
456 sinthetas, FindTextAngle(theta),
457 GetPolarLabelSize(), s);
459 }
else if (fPolarLabels){
461 textangular->SetTextAlign(FindAlign(theta));
462 textangular->PaintLatex(costhetas,sinthetas,FindTextAngle(theta),
463 GetPolarLabelSize(), fPolarLabels[i]);
467 if(fPolarLabels == NULL && optionLabels){
470 ReduceFraction(2*i, ndivMajor, rnum, rden);
471 if (rnum == 0) form = Form(
"%d",rnum);
472 if (rnum == 1 && rden == 1) form = Form(
"#pi");
473 if (rnum == 1 && rden != 1) form = Form(
"#frac{#pi}{%d}",rden);
474 if (rnum != 1 && rden == 1 && i !=0) form = Form(
"%d#pi",rnum);
475 if (rnum != 1 && rden != 1) form = Form(
"#frac{%d#pi}{%d}",rnum,rden);
476 if(theta >= 3*TMath::Pi()/12.0 && theta < 2*TMath::Pi()/3.0) corr=0.04;
477 textangular->SetTextAlign(FindAlign(theta));
478 textangular->PaintLatex(costhetas,corr+sinthetas,0,
479 GetPolarLabelSize(),form);
482 form = Form(
"%5.3g",txtval);
483 axis.LabelsLimits(form,first,last);
484 TString s = Form(
"%s",form);
485 if (first != 0) s.Remove(0, first);
486 if(theta >= 3*TMath::Pi()/12.0 && theta < 2*TMath::Pi()/3.0) corr=0.04;
487 textangular->SetTextAlign(FindAlign(theta));
488 textangular->PaintLatex(costhetas,
489 corr+sinthetas,0,GetPolarLabelSize(),s);
491 }
else if (fPolarLabels) {
493 textangular->SetTextAlign(FindAlign(theta));
494 textangular->PaintText(costhetas,sinthetas,fPolarLabels[i]);
499 Bool_t issettickpolar = gPad->GetTicky();
501 if (issettickpolar) {
502 if (theta != 0 && theta !=TMath::Pi()) {
503 gPad->PaintLine((sintheta-GetTickpolarSize())/tantheta,sintheta-GetTickpolarSize(),
504 (sintheta+GetTickpolarSize())/tantheta,sintheta+GetTickpolarSize());
506 if (theta == 0 || theta ==TMath::Pi()) {
507 gPad->PaintLine(1-GetTickpolarSize(),0,1+GetTickpolarSize(),0);
508 gPad->PaintLine(-1+GetTickpolarSize(),0,-1-GetTickpolarSize(),0);
511 TAttLine::SetLineStyle(1);
513 gPad->PaintLine(0.,0.,costheta,sintheta);
516 Int_t oldLineStyle = GetLineStyle();
517 TAttLine::SetLineStyle(2);
519 for (j=1; j<ndivMinor; j++) {
520 Double_t thetamin = theta+j*2*TMath::Pi()/(ndivMajor*ndivMinor);
521 gPad->PaintLine(0.,0.,TMath::Cos(thetamin),TMath::Sin(thetamin));
523 TAttLine::SetLineStyle(oldLineStyle);
527 Int_t big = (Int_t)fRwtmax;
533 for (i=1; i<=test; i++) {
534 Double_t txtval = pow((
double)10,(
double)(i-1));
535 Double_t theta = (i-1)*2*TMath::Pi()/(double)(test);
536 Double_t costheta = TMath::Cos(theta);
537 Double_t sintheta = TMath::Sin(theta);
538 Double_t tantheta = TMath::Tan(theta);
539 Double_t costhetas = (1+fPolarOffset)*costheta;
540 Double_t sinthetas = (1+fPolarOffset)*sintheta;
541 Double_t corr = 0.01;
543 TLatex *textangular =
new TLatex();
544 textangular->SetTextColor(GetPolarColorLabel());
545 textangular->SetTextFont(GetPolarLabelFont());
547 const char* form = (
char *)
" ";
550 if (TestBit(TGraphPolargram::kLabelOrtho)) {
551 if(fPolarLabels==NULL && optionLabels){
553 form = Form(
"%5.3g",txtval);
554 axis.LabelsLimits(form,first,last);
555 TString s = Form(
"%s",form);
556 if (first != 0) s.Remove(0, first);
557 textangular->SetTextAlign(FindAlign(theta));
558 textangular->PaintLatex(costhetas,
559 sinthetas, FindTextAngle(theta), GetPolarLabelSize(), s);
561 else if (fPolarLabels){
563 textangular->SetTextAlign(FindAlign(theta));
564 textangular->PaintText(costhetas,sinthetas,fPolarLabels[i]);
568 if(fPolarLabels==NULL && optionLabels){
570 form = Form(
"%5.3g",txtval);
571 axis.LabelsLimits(form,first,last);
572 TString s = Form(
"%s",form);
573 if (first != 0) s.Remove(0, first);
574 if(theta >= 3*TMath::Pi()/12.0 && theta < 2*TMath::Pi()/3.0) corr=0.04;
575 textangular->SetTextAlign(FindAlign(theta));
576 textangular->PaintLatex(costhetas,
577 corr+sinthetas,0,GetPolarLabelSize(),s);
578 }
else if (fPolarLabels){
580 textangular->SetTextAlign(FindAlign(theta));
581 textangular->PaintText(costhetas,sinthetas,fPolarLabels[i]);
587 Bool_t issettickpolar = gPad->GetTicky();
588 if (issettickpolar) {
589 if (theta != 0 && theta !=TMath::Pi()) {
590 gPad->PaintLine((sintheta-GetTickpolarSize())/tantheta,sintheta-GetTickpolarSize(),
591 (sintheta+GetTickpolarSize())/tantheta,sintheta+GetTickpolarSize());
593 if (theta == 0 || theta ==TMath::Pi()) {
594 gPad->PaintLine(1-GetTickpolarSize(),0,1+GetTickpolarSize(),0);
595 gPad->PaintLine(-1+GetTickpolarSize(),0,-1-GetTickpolarSize(),0);
598 TAttLine::SetLineStyle(1);
600 gPad->PaintLine(0.,0.,costheta,sintheta);
603 Int_t oldLineStyle = GetLineStyle();
604 TAttLine::SetLineStyle(2);
608 b = TMath::Log(10)*test;
609 d= 2*TMath::Pi()/(double)test;
610 for (j=1; j<9; j++) {
611 a=TMath::Log(j+1)-TMath::Log(j)+a;
613 gPad->PaintLine(0.,0.,TMath::Cos(c),TMath::Sin(c));
615 TAttLine::SetLineStyle(oldLineStyle);
625 void TGraphPolargram::PaintRadialDivisions(Bool_t drawaxis)
627 static char chopt[8] =
"";
629 Int_t ndiv = TMath::Abs(fNdivRad);
630 Int_t ndivMajor = ndiv%100;
631 Int_t ndivMinor = ndiv/100;
633 Double_t frwrmin = 0., frwrmax = 0., binWidth = 0;
635 THLimitsFinder::Optimize(fRwrmin,fRwrmax,ndivMajor,frwrmin,
636 frwrmax, ndivmajor,binWidth,
"");
639 if (!gPad->GetLogx()) {
640 gPad->RangeAxis(-1,-1,1,1);
641 gPad->Range(-1.25,-1.25,1.25,1.25);
642 Double_t umin = fRwrmin;
643 Double_t umax = fRwrmax;
644 Double_t rmajmin = (frwrmin-fRwrmin)/(fRwrmax-fRwrmin);
645 Double_t rmajmax = (frwrmax-fRwrmin)/(fRwrmax-fRwrmin);
646 Double_t dist = (rmajmax-rmajmin)/ndivmajor;
650 strncat(chopt,
"SDH", 4);
651 if (fNdivRad < 0) strncat(chopt,
"N",2);
655 axis.SetLabelSize(GetRadialLabelSize());
656 axis.SetLabelColor(GetRadialColorLabel());
657 axis.SetLabelFont(GetRadialLabelFont());
658 axis.SetLabelOffset(GetRadialOffset());
659 axis.PaintAxis(0, 0, TMath::Cos(GetAngle()), TMath::Sin(GetAngle()),
660 umin, umax, ndiv, chopt, 0., kFALSE);
665 PaintCircle(0.,0.,1,0.,360,0);
668 Double_t frwrmini = 0., frwrmaxi = 0., binWidth2 =0;
669 THLimitsFinder::Optimize(frwrmin,frwrmin+binWidth,ndivMinor,frwrmini,
670 frwrmaxi, ndivminor,binWidth2,
"");
671 Double_t dist2 = dist/(ndivminor);
673 for (i=1; i<=ndivmajor+2; i++) {
674 TAttLine::SetLineStyle(1);
676 PaintCircle(0.,0.,rmajmin,0.,360,0);
679 TAttLine::SetLineStyle(2);
681 for (j=1; j<ndivminor+1; j++) {
682 if (rmajmin+j*dist2<=1) PaintCircle(0.,0.,rmajmin+j*dist2,0.,360,0);
684 rmajmin = (frwrmin-fRwrmin)/(fRwrmax-fRwrmin)+(i-1)*dist;
690 for (i=1; i<=ndivMajor; i++) {
691 TAttLine::SetLineStyle(1);
693 Double_t rmaj = i*1./ndivMajor;
694 PaintCircle(0.,0.,rmaj,0.,360,0);
697 for (j=1; j<ndivMinor; j++) {
698 TAttLine::SetLineStyle(2);
700 PaintCircle(0.,0.,rmaj- j*1./(ndivMajor*ndivMinor),0.,360,0);
706 Int_t big = (Int_t)fRwrmax;
712 for (i=1; i<=test; i++) {
713 TAttLine::SetLineStyle(1);
716 ecart = ((double) i)/ ((double) test);
717 PaintCircle(0.,0.,ecart,0,360,0);
718 TAttLine::SetLineStyle(GetLineStyle());
722 b = TMath::Log(10)*test;
724 for (j=1; j<9; j++) {
725 a = TMath::Log(j+1)-TMath::Log(j)+a;
727 PaintCircle(0,0.,c,0.,360,0);
731 TAttLine::SetLineStyle(1);
738 void TGraphPolargram::ReduceFraction(Int_t num, Int_t den, Int_t &rnum, Int_t &rden)
751 for (i=j; i > 1; i--) {
752 if ((a % i == 0) && (b % i == 0)) {
764 void TGraphPolargram::SetAxisAngle(Double_t angle)
766 fAxisAngle = angle/180*TMath::Pi();
774 void TGraphPolargram::SetNdivPolar(Int_t ndiv)
778 if (gPad) gPad->Modified();
786 void TGraphPolargram::SetNdivRadial(Int_t ndiv)
789 if (gPad) gPad->Modified();
795 void TGraphPolargram::SetPolarLabel(Int_t div,
const TString & label)
797 if(fPolarLabels == NULL)
798 fPolarLabels =
new TString[fNdivPol];
799 fPolarLabels[div]=label;
800 if (gPad) gPad->Modified();
806 void TGraphPolargram::SetPolarLabelColor(Color_t tcolorangular )
808 fPolarLabelColor = tcolorangular;
813 void TGraphPolargram::SetPolarLabelFont(Font_t tfontangular)
817 fPolarLabelFont = tfontangular;
823 void TGraphPolargram::SetPolarLabelSize(Double_t angularsize )
825 fPolarTextSize = angularsize;
831 void TGraphPolargram::SetPolarOffset(Double_t angularOffset)
833 fPolarOffset = angularOffset;
834 if (gPad) gPad->Modified();
840 void TGraphPolargram::SetRadialLabelColor(Color_t tcolorradial )
842 fRadialLabelColor = tcolorradial;
848 void TGraphPolargram::SetRadialLabelFont(Font_t tfontradial)
850 fRadialLabelFont = tfontradial;
856 void TGraphPolargram::SetRadialLabelSize(Double_t radialsize )
858 fRadialTextSize = radialsize;
864 void TGraphPolargram::SetRadialOffset(Double_t radialOffset)
866 fRadialOffset = radialOffset;
867 if (gPad) gPad->Modified();
875 void TGraphPolargram::SetRangePolar(Double_t tmin, Double_t tmax)
885 if (gPad) gPad->Modified();
893 void TGraphPolargram::SetRangeRadial(Double_t rmin, Double_t rmax)
899 if (gPad) gPad->Modified();
905 void TGraphPolargram::SetTickpolarSize(Double_t tickpolarsize)
907 fTickpolarSize = tickpolarsize;
913 void TGraphPolargram::SetToDegree()
918 ChangeRangePolar(0,360);
924 void TGraphPolargram::SetToGrad()
929 ChangeRangePolar(0,200);
935 void TGraphPolargram::SetToRadian()
940 ChangeRangePolar(0,2*TMath::Pi());
946 void TGraphPolargram::SetTwoPi()
948 SetRangePolar(0,2*TMath::Pi());