22 const Double_t kPI = 3.14159265358979323846;
55 TEllipse::TEllipse(): TObject(), TAttLine(), TAttFill()
69 TEllipse::TEllipse(Double_t x1, Double_t y1,Double_t r1,Double_t r2,Double_t phimin,Double_t phimax,Double_t theta)
70 :TObject(), TAttLine(), TAttFill(0,1001)
79 if (r2 <= 0) fR2 = fR1;
92 TEllipse::TEllipse(
const TEllipse &ellipse) : TObject(ellipse), TAttLine(ellipse), TAttFill(ellipse), TAttBBox2D(ellipse)
102 ((TEllipse&)ellipse).Copy(*
this);
108 void TEllipse::Copy(TObject &obj)
const
111 TAttLine::Copy(((TEllipse&)obj));
112 TAttFill::Copy(((TEllipse&)obj));
113 ((TEllipse&)obj).fX1 = fX1;
114 ((TEllipse&)obj).fY1 = fY1;
115 ((TEllipse&)obj).fR1 = fR1;
116 ((TEllipse&)obj).fR2 = fR2;
117 ((TEllipse&)obj).fPhimin = fPhimin;
118 ((TEllipse&)obj).fPhimax = fPhimax;
119 ((TEllipse&)obj).fTheta = fTheta;
131 Int_t TEllipse::DistancetoPrimitive(Int_t px, Int_t py)
133 Double_t x = gPad->PadtoX(gPad->AbsPixeltoX(px));
134 Double_t y = gPad->PadtoY(gPad->AbsPixeltoY(py));
136 Double_t dxnr = x - fX1;
137 Double_t dynr = y - fY1;
139 Double_t ct = TMath::Cos(kPI*GetTheta()/180.0);
140 Double_t st = TMath::Sin(kPI*GetTheta()/180.0);
142 Double_t dx = dxnr*ct + dynr*st;
143 Double_t dy = -dxnr*st + dynr*ct;
148 if (dx == 0 || r1 == 0 || r2 == 0)
return 9999;
149 Double_t distp = TMath::Sqrt(dx*dx + dy*dy);
151 Double_t tana = dy/dx;
153 Double_t distr = TMath::Sqrt((1+tana)/(1.0/(r1*r1) + tana/(r2*r2)));
155 if (GetFillColor() && GetFillStyle()) {
156 if (distr > distp) dist = 0;
158 if (TMath::Abs(distr-distp)/(r1+r2) < 0.01) dist = 0;
166 void TEllipse::Draw(Option_t *option)
174 void TEllipse::DrawEllipse(Double_t x1, Double_t y1,Double_t r1,Double_t r2,Double_t phimin,Double_t phimax,Double_t theta,Option_t *option)
176 TEllipse *newellipse =
new TEllipse(x1, y1, r1, r2, phimin, phimax,theta);
177 TAttLine::Copy(*newellipse);
178 TAttFill::Copy(*newellipse);
179 newellipse->SetBit(kCanDelete);
180 newellipse->AppendPad(option);
181 if (TestBit(kNoEdges)) newellipse->SetBit(kNoEdges);
197 void TEllipse::ExecuteEvent(Int_t event, Int_t px, Int_t py)
204 Double_t angle,dx,dy,dphi,ct,st,fTy,fBy,fLx,fRx;
205 static Int_t px1,py1,npe,r1,r2,sav1,sav2;
206 const Int_t kMinSize = 25;
208 static Bool_t pTop, pL, pR, pBot, pINSIDE;
209 static Int_t pTx,pTy,pLx,pLy,pRx,pRy,pBx,pBy;
210 static Int_t x[np+2], y[np+2];
211 static Int_t pxold, pyold;
212 static Int_t sig,impair;
213 static Double_t sdx, sdy;
214 static Double_t oldX1, oldY1, oldR1, oldR2;
216 Bool_t opaque = gPad->OpaqueMoving();
218 if (!gPad->IsEditable())
return;
228 dphi = (fPhimax-fPhimin)*kPI/(180*np);
229 ct = TMath::Cos(kPI*fTheta/180);
230 st = TMath::Sin(kPI*fTheta/180);
232 angle = fPhimin*kPI/180 + Double_t(i)*dphi;
233 dx = fR1*TMath::Cos(angle);
234 dy = fR2*TMath::Sin(angle);
235 x[i] = gPad->XtoAbsPixel(fX1 + dx*ct - dy*st);
236 y[i] = gPad->YtoAbsPixel(fY1 + dx*st + dy*ct);
238 if (fPhimax-fPhimin >= 360 ) {
243 x[np] = gPad->XtoAbsPixel(fX1);
244 y[np] = gPad->YtoAbsPixel(fY1);
250 px1 = gPad->XtoAbsPixel(fX1);
251 py1 = gPad->YtoAbsPixel(fY1);
254 pTy = gPad->YtoAbsPixel(fR2+fY1);
255 pBy = gPad->YtoAbsPixel(-fR2+fY1);
256 pLx = gPad->XtoAbsPixel(-fR1+fX1);
257 pRx = gPad->XtoAbsPixel(fR1+fX1);
261 gVirtualX->SetLineColor(-1);
263 gVirtualX->DrawLine(pRx+4, py1+4, pRx-4, py1+4);
264 gVirtualX->DrawLine(pRx-4, py1+4, pRx-4, py1-4);
265 gVirtualX->DrawLine(pRx-4, py1-4, pRx+4, py1-4);
266 gVirtualX->DrawLine(pRx+4, py1-4, pRx+4, py1+4);
267 gVirtualX->DrawLine(pLx+4, py1+4, pLx-4, py1+4);
268 gVirtualX->DrawLine(pLx-4, py1+4, pLx-4, py1-4);
269 gVirtualX->DrawLine(pLx-4, py1-4, pLx+4, py1-4);
270 gVirtualX->DrawLine(pLx+4, py1-4, pLx+4, py1+4);
271 gVirtualX->DrawLine(px1+4, pBy+4, px1-4, pBy+4);
272 gVirtualX->DrawLine(px1-4, pBy+4, px1-4, pBy-4);
273 gVirtualX->DrawLine(px1-4, pBy-4, px1+4, pBy-4);
274 gVirtualX->DrawLine(px1+4, pBy-4, px1+4, pBy+4);
275 gVirtualX->DrawLine(px1+4, pTy+4, px1-4, pTy+4);
276 gVirtualX->DrawLine(px1-4, pTy+4, px1-4, pTy-4);
277 gVirtualX->DrawLine(px1-4, pTy-4, px1+4, pTy-4);
278 gVirtualX->DrawLine(px1+4, pTy-4, px1+4, pTy+4);
281 sdx = this->GetX1()-gPad->AbsPixeltoX(px);
282 sdy = this->GetY1()-gPad->AbsPixeltoY(py);
287 px1 = gPad->XtoAbsPixel(fX1);
288 py1 = gPad->YtoAbsPixel(fY1);
291 pTy = gPad->YtoAbsPixel(fR2+fY1);
292 pBy = gPad->YtoAbsPixel(-fR2+fY1);
293 pLx = gPad->XtoAbsPixel(-fR1+fX1);
294 pRx = gPad->XtoAbsPixel(fR1+fX1);
295 pTop = pL = pR = pBot = pINSIDE = kFALSE;
296 if ((TMath::Abs(px - pTx) < kMaxDiff) &&
297 (TMath::Abs(py - pTy) < kMaxDiff)) {
299 gPad->SetCursor(kTopSide);
302 if ((TMath::Abs(px - pBx) < kMaxDiff) &&
303 (TMath::Abs(py - pBy) < kMaxDiff)) {
305 gPad->SetCursor(kBottomSide);
308 if ((TMath::Abs(py - pLy) < kMaxDiff) &&
309 (TMath::Abs(px - pLx) < kMaxDiff)) {
311 gPad->SetCursor(kLeftSide);
314 if ((TMath::Abs(py - pRy) < kMaxDiff) &&
315 (TMath::Abs(px - pRx) < kMaxDiff)) {
317 gPad->SetCursor(kRightSide);
319 else {pINSIDE= kTRUE; gPad->SetCursor(kMove); }
320 pxold = px; pyold = py;
324 case kArrowKeyRelease:
328 gVirtualX->DrawLine(pRx+4, py1+4, pRx-4, py1+4);
329 gVirtualX->DrawLine(pRx-4, py1+4, pRx-4, py1-4);
330 gVirtualX->DrawLine(pRx-4, py1-4, pRx+4, py1-4);
331 gVirtualX->DrawLine(pRx+4, py1-4, pRx+4, py1+4);
332 gVirtualX->DrawLine(pLx+4, py1+4, pLx-4, py1+4);
333 gVirtualX->DrawLine(pLx-4, py1+4, pLx-4, py1-4);
334 gVirtualX->DrawLine(pLx-4, py1-4, pLx+4, py1-4);
335 gVirtualX->DrawLine(pLx+4, py1-4, pLx+4, py1+4);
336 gVirtualX->DrawLine(px1+4, pBy+4, px1-4, pBy+4);
337 gVirtualX->DrawLine(px1-4, pBy+4, px1-4, pBy-4);
338 gVirtualX->DrawLine(px1-4, pBy-4, px1+4, pBy-4);
339 gVirtualX->DrawLine(px1+4, pBy-4, px1+4, pBy+4);
340 gVirtualX->DrawLine(px1+4, pTy+4, px1-4, pTy+4);
341 gVirtualX->DrawLine(px1-4, pTy+4, px1-4, pTy-4);
342 gVirtualX->DrawLine(px1-4, pTy-4, px1+4, pTy-4);
343 gVirtualX->DrawLine(px1+4, pTy-4, px1+4, pTy+4);
344 for (i=0;i<npe;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
349 py1 += (py - pyold)/2;
350 r2 -= (py - pyold)/2;
351 if (TMath::Abs(pyold-py)%2==1) impair++;
352 if (py-pyold>0) sig=+1;
354 if (impair==2) { impair = 0; py1 += sig; r2 -= sig;}
355 if (py1 > pBy-kMinSize) {py1 = sav1; r2 = sav2; py = pyold;}
360 py1 += (py - pyold)/2;
361 r2 += (py - pyold)/2;
362 if (TMath::Abs(pyold-py)%2==1) impair++;
363 if (py-pyold>0) sig=+1;
365 if (impair==2) { impair = 0; py1 += sig; r2 += sig;}
366 if (py1 < pTy+kMinSize) {py1 = sav1; r2 = sav2; py = pyold;}
371 px1 += (px - pxold)/2;
372 r1 -= (px - pxold)/2;
373 if (TMath::Abs(pxold-px)%2==1) impair++;
374 if (px-pxold>0) sig=+1;
376 if (impair==2) { impair = 0; px1 += sig; r1 -= sig;}
377 if (px1 > pRx-kMinSize) {px1 = sav1; r1 = sav2; px = pxold;}
382 px1 += (px - pxold)/2;
383 r1 += (px - pxold)/2;
384 if (TMath::Abs(pxold-px)%2==1) impair++;
385 if (px-pxold>0) sig=+1;
387 if (impair==2) { impair = 0; px1 += sig; r1 += sig;}
388 if (px1 < pLx+kMinSize) {px1 = sav1; r1 = sav2; px = pxold;}
390 if (pTop || pBot || pL || pR) {
392 dphi = (fPhimax-fPhimin)*kPI/(180*np);
393 ct = TMath::Cos(kPI*fTheta/180);
394 st = TMath::Sin(kPI*fTheta/180);
396 angle = fPhimin*kPI/180 + Double_t(i)*dphi;
397 dx = r1*TMath::Cos(angle);
398 dy = r2*TMath::Sin(angle);
399 x[i] = px1 + Int_t(dx*ct - dy*st);
400 y[i] = py1 + Int_t(dx*st + dy*ct);
402 if (fPhimax-fPhimin >= 360 ) {
413 gVirtualX->SetLineColor(-1);
416 gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
420 this->SetX1(gPad->AbsPixeltoX(px1));
421 this->SetY1(gPad->AbsPixeltoY(py1));
422 this->SetR1(TMath::Abs(gPad->AbsPixeltoX(px1-r1)-gPad->AbsPixeltoX(px1+r1))/2);
423 this->SetR2(TMath::Abs(gPad->AbsPixeltoY(py1-r2)-gPad->AbsPixeltoY(py1+r2))/2);
424 if (pTop) gPad->ShowGuidelines(
this, event,
't',
true);
425 if (pBot) gPad->ShowGuidelines(
this, event,
'b',
true);
426 if (pL) gPad->ShowGuidelines(
this, event,
'l',
true);
427 if (pR) gPad->ShowGuidelines(
this, event,
'r',
true);
428 gPad->Modified(kTRUE);
434 dpx = px-pxold; dpy = py-pyold;
435 px1 += dpx; py1 += dpy;
436 for (i=0;i<=npe;i++) { x[i] += dpx; y[i] += dpy;}
437 for (i=0;i<npe;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
440 this->SetX1(gPad->AbsPixeltoX(px)+sdx);
441 this->SetY1(gPad->AbsPixeltoY(py)+sdy);
442 gPad->ShowGuidelines(
this, event,
'i',
true);
443 gPad->Modified(kTRUE);
454 gVirtualX->DrawLine(pRx+4, py1+4, pRx-4, py1+4);
455 gVirtualX->DrawLine(pRx-4, py1+4, pRx-4, py1-4);
456 gVirtualX->DrawLine(pRx-4, py1-4, pRx+4, py1-4);
457 gVirtualX->DrawLine(pRx+4, py1-4, pRx+4, py1+4);
458 gVirtualX->DrawLine(pLx+4, py1+4, pLx-4, py1+4);
459 gVirtualX->DrawLine(pLx-4, py1+4, pLx-4, py1-4);
460 gVirtualX->DrawLine(pLx-4, py1-4, pLx+4, py1-4);
461 gVirtualX->DrawLine(pLx+4, py1-4, pLx+4, py1+4);
462 gVirtualX->DrawLine(px1+4, pBy+4, px1-4, pBy+4);
463 gVirtualX->DrawLine(px1-4, pBy+4, px1-4, pBy-4);
464 gVirtualX->DrawLine(px1-4, pBy-4, px1+4, pBy-4);
465 gVirtualX->DrawLine(px1+4, pBy-4, px1+4, pBy+4);
466 gVirtualX->DrawLine(px1+4, pTy+4, px1-4, pTy+4);
467 gVirtualX->DrawLine(px1-4, pTy+4, px1-4, pTy-4);
468 gVirtualX->DrawLine(px1-4, pTy-4, px1+4, pTy-4);
469 gVirtualX->DrawLine(px1+4, pTy-4, px1+4, pTy+4);
476 if (gROOT->IsEscaped()) {
477 gROOT->SetEscape(kFALSE);
483 gPad->Modified(kTRUE);
490 gPad->ShowGuidelines(
this, event);
492 fX1 = gPad->AbsPixeltoX(px1);
493 fY1 = gPad->AbsPixeltoY(py1);
494 fBy = gPad->AbsPixeltoY(py1+r2);
495 fTy = gPad->AbsPixeltoY(py1-r2);
496 fLx = gPad->AbsPixeltoX(px1+r1);
497 fRx = gPad->AbsPixeltoX(px1-r1);
498 fR1 = TMath::Abs(fRx-fLx)/2;
499 fR2 = TMath::Abs(fTy-fBy)/2;
500 gPad->Modified(kTRUE);
501 gVirtualX->SetLineColor(-1);
509 void TEllipse::ls(Option_t *)
const
511 TROOT::IndentLevel();
512 printf(
"%s: X1= %f Y1=%f R1=%f R2=%f\n",GetName(),fX1,fY1,fR1,fR2);
518 void TEllipse::Paint(Option_t *option)
520 PaintEllipse(fX1,fY1,fR1,fR2,fPhimin,fPhimax,fTheta,option);
526 void TEllipse::PaintEllipse(Double_t x1, Double_t y1, Double_t r1, Double_t r2,
527 Double_t phimin, Double_t phimax, Double_t theta,
530 const Int_t np = 200;
531 static Double_t x[np+3], y[np+3];
535 Double_t phi1 = TMath::Min(phimin,phimax);
536 Double_t phi2 = TMath::Max(phimin,phimax);
539 Double_t circ = kPI*(r1+r2)*(phi2-phi1)/360;
540 Int_t n = (Int_t)(np*circ/((gPad->GetX2()-gPad->GetX1())+(gPad->GetY2()-gPad->GetY1())));
543 Double_t angle,dx,dy;
544 Double_t dphi = (phi2-phi1)*kPI/(180*n);
545 Double_t ct = TMath::Cos(kPI*theta/180);
546 Double_t st = TMath::Sin(kPI*theta/180);
547 for (Int_t i=0;i<=n;i++) {
548 angle = phi1*kPI/180 + Double_t(i)*dphi;
549 dx = r1*TMath::Cos(angle);
550 dy = r2*TMath::Sin(angle);
551 x[i] = gPad->XtoPad(x1 + dx*ct - dy*st);
552 y[i] = gPad->YtoPad(y1 + dx*st + dy*ct);
554 TString opt = option;
556 if (phi2-phi1 >= 360 ) {
557 if (GetFillStyle()) gPad->PaintFillArea(n,x,y);
558 if (GetLineStyle()) gPad->PaintPolyLine(n+1,x,y);
560 x[n+1] = gPad->XtoPad(x1);
561 y[n+1] = gPad->YtoPad(y1);
564 if (GetFillStyle()) gPad->PaintFillArea(n+2,x,y);
565 if (GetLineStyle()) {
566 if (TestBit(kNoEdges) || opt.Contains(
"only")) gPad->PaintPolyLine(n+1,x,y);
567 else gPad->PaintPolyLine(n+3,x,y);
575 void TEllipse::Print(Option_t *)
const
577 printf(
"Ellipse: X1=%f Y1=%f R1=%f R2=%f",fX1,fY1,fR1,fR2);
578 if (GetLineColor() != 1) printf(
" Color=%d",GetLineColor());
579 if (GetLineStyle() != 1) printf(
" Style=%d",GetLineStyle());
580 if (GetLineWidth() != 1) printf(
" Width=%d",GetLineWidth());
587 void TEllipse::SavePrimitive(std::ostream &out, Option_t * )
590 if (gROOT->ClassSaved(TEllipse::Class())) {
595 out<<
"ellipse = new TEllipse("<<fX1<<
","<<fY1<<
","<<fR1<<
","<<fR2
596 <<
","<<fPhimin<<
","<<fPhimax<<
","<<fTheta<<
");"<<std::endl;
598 SaveFillAttributes(out,
"ellipse",0,1001);
599 SaveLineAttributes(out,
"ellipse",1,1,1);
601 if (GetNoEdges()) out<<
" ellipse->SetNoEdges();"<<std::endl;
603 out<<
" ellipse->Draw();"<<std::endl;
609 Bool_t TEllipse::GetNoEdges()
const
611 return TestBit(kNoEdges) ? kTRUE : kFALSE;
619 void TEllipse::SetNoEdges(Bool_t noEdges)
621 if (noEdges) SetBit(kNoEdges);
622 else ResetBit(kNoEdges);
628 void TEllipse::Streamer(TBuffer &R__b)
630 if (R__b.IsReading()) {
632 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
634 R__b.ReadClassBuffer(TEllipse::Class(),
this, R__v, R__s, R__c);
638 TObject::Streamer(R__b);
639 TAttLine::Streamer(R__b);
640 TAttFill::Streamer(R__b);
641 Float_t x1,y1,r1,r2,phimin,phimax,theta;
642 R__b >> x1; fX1 = x1;
643 R__b >> y1; fY1 = y1;
644 R__b >> r1; fR1 = r1;
645 R__b >> r2; fR2 = r2;
646 R__b >> phimin; fPhimin = phimin;
647 R__b >> phimax; fPhimax = phimax;
648 R__b >> theta; fTheta = theta;
649 R__b.CheckByteCount(R__s, R__c, TEllipse::IsA());
653 R__b.WriteClassBuffer(TEllipse::Class(),
this);
661 Rectangle_t TEllipse::GetBBox()
664 BBox.fX = gPad->XtoPixel(fX1-fR1);
665 BBox.fY = gPad->YtoPixel(fY1+fR2);
666 BBox.fWidth = gPad->XtoPixel(fX1+fR1)-gPad->XtoPixel(fX1-fR1);
667 BBox.fHeight = gPad->YtoPixel(fY1-fR2)-gPad->YtoPixel(fY1+fR2);
674 TPoint TEllipse::GetBBoxCenter()
677 p.SetX(gPad->XtoPixel(fX1));
678 p.SetY(gPad->YtoPixel(fY1));
685 void TEllipse::SetBBoxCenter(
const TPoint &p)
687 fX1 = gPad->PixeltoX(p.GetX());
688 fY1 = gPad->PixeltoY(p.GetY()-gPad->VtoPixel(0));
694 void TEllipse::SetBBoxCenterX(
const Int_t x)
696 fX1 = gPad->PixeltoX(x);
702 void TEllipse::SetBBoxCenterY(
const Int_t y)
704 fY1 = gPad->PixeltoY(y-gPad->VtoPixel(0));
711 void TEllipse::SetBBoxX1(
const Int_t x)
713 Double_t x1 = gPad->PixeltoX(x);
714 if (x1>fX1+fR1)
return;
716 fR1 = (fX1+fR1-x1)*0.5;
724 void TEllipse::SetBBoxX2(
const Int_t x)
726 Double_t x2 = gPad->PixeltoX(x);
727 if (x2<fX1-fR1)
return;
729 fR1 = (x2-fX1+fR1)*0.5;
736 void TEllipse::SetBBoxY1(
const Int_t y)
738 Double_t y1 = gPad->PixeltoY(y-gPad->VtoPixel(0));
739 if (y1<fY1-fR2)
return;
741 fR2 = (y1-fY1+fR2)*0.5;
749 void TEllipse::SetBBoxY2(
const Int_t y)
751 Double_t y2 = gPad->PixeltoY(y-gPad->VtoPixel(0));
753 if (y2>fY1+fR2)
return;
755 fR2 = (fY1+fR2-y2)*0.5;