Logo ROOT  
Reference Guide
Loading...
Searching...
No Matches
TEllipse.cxx
Go to the documentation of this file.
1// @(#)root/graf:$Id$
2// Author: Rene Brun 16/10/95
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 <cstdlib>
13
14#include <iostream>
15#include "TROOT.h"
16#include "TBuffer.h"
17#include "TEllipse.h"
18#include "TVirtualPad.h"
19#include "TMath.h"
20#include "TPoint.h"
21#include "TVirtualX.h"
22
23
24constexpr Double_t kPI = TMath::Pi();
25
26
27/** \class TEllipse
28\ingroup BasicGraphics
29
30Draw Ellipses.
31
32The ellipse can be truncated and rotated. It is defined by its center `(x1,y1)`
33and two radius `r1` and `r2`.
34
35A minimum and maximum angle may be specified `(phimin, phimax)`.
36The ellipse may be rotated with an angle `theta`. All these
37angles are in degrees.
38The attributes of the outline line are given via `TAttLine`.
39The attributes of the fill area are given via `TAttFill`.
40The picture below illustrates different types of ellipses.
41
42When an ellipse sector only is drawn, the lines connecting the center
43of the ellipse to the edges are drawn by default. One can specify
44the drawing option "only" to not draw these lines or alternatively
45call the function `SetNoEdges()`. To remove completely the ellipse
46outline it is enough to specify 0 as line style.
47
48Begin_Macro(source)
49../../../tutorials/visualisation/graphics/ellipse.C
50End_Macro
51*/
52
53////////////////////////////////////////////////////////////////////////////////
54/// Ellipse default constructor.
55
57{
58 fX1 = 0;
59 fY1 = 0;
60 fR1 = 1;
61 fR2 = 1;
62 fPhimin = 0;
63 fPhimax = 360;
64 fTheta = 0;
65}
66
67////////////////////////////////////////////////////////////////////////////////
68/// Ellipse normal constructor.
69
71 :TObject(), TAttLine(), TAttFill(0,1001)
72{
73 fX1 = x1;
74 fY1 = y1;
75 fR1 = r1;
76 fR2 = r2;
77 fPhimin = phimin;
78 fPhimax = phimax;
79 fTheta = theta;
80 if (r2 <= 0) fR2 = fR1;
81}
82
83////////////////////////////////////////////////////////////////////////////////
84/// Ellipse default destructor.
85
87{
88}
89
90////////////////////////////////////////////////////////////////////////////////
91/// Copy constructor.
92
93TEllipse::TEllipse(const TEllipse &ellipse) : TObject(ellipse), TAttLine(ellipse), TAttFill(ellipse), TAttBBox2D(ellipse)
94{
95 fX1 = 0;
96 fY1 = 0;
97 fR1 = 1;
98 fR2 = 1;
99 fPhimin = 0;
100 fPhimax = 360;
101 fTheta = 0;
102
103 ellipse.TEllipse::Copy(*this);
104}
105
106////////////////////////////////////////////////////////////////////////////////
107/// Copy this ellipse to ellipse.
108
109void TEllipse::Copy(TObject &obj) const
110{
111 TObject::Copy(obj);
112 TAttLine::Copy(((TEllipse&)obj));
113 TAttFill::Copy(((TEllipse&)obj));
114 ((TEllipse&)obj).fX1 = fX1;
115 ((TEllipse&)obj).fY1 = fY1;
116 ((TEllipse&)obj).fR1 = fR1;
117 ((TEllipse&)obj).fR2 = fR2;
118 ((TEllipse&)obj).fPhimin = fPhimin;
119 ((TEllipse&)obj).fPhimax = fPhimax;
120 ((TEllipse&)obj).fTheta = fTheta;
121}
122
123////////////////////////////////////////////////////////////////////////////////
124/// Compute distance from point px,py to an ellipse.
125///
126/// Compute the closest distance of approach from point px,py to this
127/// ellipse. The distance is computed in pixels units.
128///
129/// In case of a filled ellipse the distance returned is 0 if the point
130/// (px,py) is inside the ellipse, and is huge if the point is outside.
131
133{
134 if (!gPad) return 9999;
135 Double_t x = gPad->PadtoX(gPad->AbsPixeltoX(px));
136 Double_t y = gPad->PadtoY(gPad->AbsPixeltoY(py));
137
138 Double_t dxnr = x - fX1;
139 Double_t dynr = y - fY1;
140
141 Double_t ct = TMath::Cos(kPI*GetTheta()/180.0);
142 Double_t st = TMath::Sin(kPI*GetTheta()/180.0);
143
144 Double_t dx = dxnr*ct + dynr*st;
145 Double_t dy = -dxnr*st + dynr*ct;
146
147 Double_t r1 = fR1;
148 Double_t r2 = fR2;
149
150 if (dx == 0 || r1 == 0 || r2 == 0) return 9999;
151 Double_t distp = TMath::Sqrt(dx*dx + dy*dy);
152
153 Double_t tana = dy/dx;
154 tana *= tana;
155 Double_t distr = TMath::Sqrt((1+tana)/(1.0/(r1*r1) + tana/(r2*r2)));
156 Int_t dist = 9999;
157 if (GetFillColor() && GetFillStyle()) {
158 if (distr > distp) dist = 0;
159 } else {
160 if (TMath::Abs(distr-distp)/(r1+r2) < 0.01) dist = 0;
161 }
162 return dist;
163}
164
165////////////////////////////////////////////////////////////////////////////////
166/// Draw this ellipse with its current attributes.
167
168void TEllipse::Draw(Option_t *option)
169{
170 AppendPad(option);
171}
172
173////////////////////////////////////////////////////////////////////////////////
174/// Draw this ellipse with new coordinates.
175
177{
178 TEllipse *newellipse = new TEllipse(x1, y1, r1, r2, phimin, phimax,theta);
179 TAttLine::Copy(*newellipse);
180 TAttFill::Copy(*newellipse);
181 newellipse->SetBit(kCanDelete);
182 newellipse->AppendPad(option);
183 if (TestBit(kNoEdges)) newellipse->SetBit(kNoEdges);
184 return newellipse;
185}
186
187////////////////////////////////////////////////////////////////////////////////
188/// Execute action corresponding to one event.
189///
190/// This member function is called when a line is clicked with the locator
191///
192/// If Left button clicked on one of the line end points, this point
193/// follows the cursor until button is released.
194///
195/// if Middle button clicked, the line is moved parallel to itself
196/// until the button is released.
197///
198/// NOTE that support for log scale is not implemented
199
200void TEllipse::ExecuteEvent(Int_t event, Int_t px, Int_t py)
201{
202 if (!gPad) return;
203
204 Int_t kMaxDiff = 10;
205
206 Int_t i, dpx, dpy;
208 static Int_t px1,py1,npe,r1,r2,sav1,sav2;
209 const Int_t kMinSize = 25;
210 const Int_t np = 40;
211 static Bool_t pTop, pL, pR, pBot, pINSIDE;
212 static Int_t pTx,pTy,pLx,pLy,pRx,pRy,pBx,pBy;
213 static Int_t x[np+2], y[np+2];
214 static Int_t pxold, pyold;
215 static Int_t sig,impair;
216 static Double_t sdx, sdy;
217 static Double_t oldX1, oldY1, oldR1, oldR2;
218
219 Bool_t opaque = gPad->OpaqueMoving();
220
221 if (!gPad->IsEditable()) return;
222
223 switch (event) {
224
225 case kArrowKeyPress:
226 case kButton1Down:
227 oldX1 = fX1;
228 oldY1 = fY1;
229 oldR1 = fR1;
230 oldR2 = fR2;
231 dphi = (fPhimax-fPhimin)*kPI/(180*np);
232 ct = TMath::Cos(kPI*fTheta/180);
233 st = TMath::Sin(kPI*fTheta/180);
234 for (i=0;i<np;i++) {
235 angle = fPhimin*kPI/180 + Double_t(i)*dphi;
238 x[i] = gPad->XtoAbsPixel(fX1 + dx*ct - dy*st);
239 y[i] = gPad->YtoAbsPixel(fY1 + dx*st + dy*ct);
240 }
241 if (fPhimax-fPhimin >= 360 ) {
242 x[np] = x[0];
243 y[np] = y[0];
244 npe = np;
245 } else {
246 x[np] = gPad->XtoAbsPixel(fX1);
247 y[np] = gPad->YtoAbsPixel(fY1);
248 x[np+1] = x[0];
249 y[np+1] = y[0];
250 npe = np + 1;
251 }
252 impair = 0;
253 px1 = gPad->XtoAbsPixel(fX1);
254 py1 = gPad->YtoAbsPixel(fY1);
255 pTx = pBx = px1;
256 pLy = pRy = py1;
257 pTy = gPad->YtoAbsPixel(fR2+fY1);
258 pBy = gPad->YtoAbsPixel(-fR2+fY1);
259 pLx = gPad->XtoAbsPixel(-fR1+fX1);
260 pRx = gPad->XtoAbsPixel(fR1+fX1);
261 r2 = (pBy-pTy)/2;
262 r1 = (pRx-pLx)/2;
263 if (!opaque) {
264 gVirtualX->SetLineColor(-1);
266 gVirtualX->DrawLine(pRx+4, py1+4, pRx-4, py1+4);
267 gVirtualX->DrawLine(pRx-4, py1+4, pRx-4, py1-4);
268 gVirtualX->DrawLine(pRx-4, py1-4, pRx+4, py1-4);
269 gVirtualX->DrawLine(pRx+4, py1-4, pRx+4, py1+4);
270 gVirtualX->DrawLine(pLx+4, py1+4, pLx-4, py1+4);
271 gVirtualX->DrawLine(pLx-4, py1+4, pLx-4, py1-4);
272 gVirtualX->DrawLine(pLx-4, py1-4, pLx+4, py1-4);
273 gVirtualX->DrawLine(pLx+4, py1-4, pLx+4, py1+4);
274 gVirtualX->DrawLine(px1+4, pBy+4, px1-4, pBy+4);
275 gVirtualX->DrawLine(px1-4, pBy+4, px1-4, pBy-4);
276 gVirtualX->DrawLine(px1-4, pBy-4, px1+4, pBy-4);
277 gVirtualX->DrawLine(px1+4, pBy-4, px1+4, pBy+4);
278 gVirtualX->DrawLine(px1+4, pTy+4, px1-4, pTy+4);
279 gVirtualX->DrawLine(px1-4, pTy+4, px1-4, pTy-4);
280 gVirtualX->DrawLine(px1-4, pTy-4, px1+4, pTy-4);
281 gVirtualX->DrawLine(px1+4, pTy-4, px1+4, pTy+4);
282 }
283 else {
284 sdx = this->GetX1()-gPad->AbsPixeltoX(px);
285 sdy = this->GetY1()-gPad->AbsPixeltoY(py);
286 }
287 // No break !!!
288
289 case kMouseMotion:
290 px1 = gPad->XtoAbsPixel(fX1);
291 py1 = gPad->YtoAbsPixel(fY1);
292 pTx = pBx = px1;
293 pLy = pRy = py1;
294 pTy = gPad->YtoAbsPixel(fR2+fY1);
295 pBy = gPad->YtoAbsPixel(-fR2+fY1);
296 pLx = gPad->XtoAbsPixel(-fR1+fX1);
297 pRx = gPad->XtoAbsPixel(fR1+fX1);
298 pTop = pL = pR = pBot = pINSIDE = kFALSE;
299 if ((TMath::Abs(px - pTx) < kMaxDiff) &&
300 (TMath::Abs(py - pTy) < kMaxDiff)) { // top edge
301 pTop = kTRUE;
302 gPad->SetCursor(kTopSide);
303 }
304 else
305 if ((TMath::Abs(px - pBx) < kMaxDiff) &&
306 (TMath::Abs(py - pBy) < kMaxDiff)) { // bottom edge
307 pBot = kTRUE;
308 gPad->SetCursor(kBottomSide);
309 }
310 else
311 if ((TMath::Abs(py - pLy) < kMaxDiff) &&
312 (TMath::Abs(px - pLx) < kMaxDiff)) { // left edge
313 pL = kTRUE;
314 gPad->SetCursor(kLeftSide);
315 }
316 else
317 if ((TMath::Abs(py - pRy) < kMaxDiff) &&
318 (TMath::Abs(px - pRx) < kMaxDiff)) { // right edge
319 pR = kTRUE;
320 gPad->SetCursor(kRightSide);
321 }
322 else {pINSIDE= kTRUE; gPad->SetCursor(kMove); }
323 pxold = px; pyold = py;
324
325 break;
326
327 case kArrowKeyRelease:
328 case kButton1Motion:
329 if (!opaque)
330 {
331 gVirtualX->DrawLine(pRx+4, py1+4, pRx-4, py1+4);
332 gVirtualX->DrawLine(pRx-4, py1+4, pRx-4, py1-4);
333 gVirtualX->DrawLine(pRx-4, py1-4, pRx+4, py1-4);
334 gVirtualX->DrawLine(pRx+4, py1-4, pRx+4, py1+4);
335 gVirtualX->DrawLine(pLx+4, py1+4, pLx-4, py1+4);
336 gVirtualX->DrawLine(pLx-4, py1+4, pLx-4, py1-4);
337 gVirtualX->DrawLine(pLx-4, py1-4, pLx+4, py1-4);
338 gVirtualX->DrawLine(pLx+4, py1-4, pLx+4, py1+4);
339 gVirtualX->DrawLine(px1+4, pBy+4, px1-4, pBy+4);
340 gVirtualX->DrawLine(px1-4, pBy+4, px1-4, pBy-4);
341 gVirtualX->DrawLine(px1-4, pBy-4, px1+4, pBy-4);
342 gVirtualX->DrawLine(px1+4, pBy-4, px1+4, pBy+4);
343 gVirtualX->DrawLine(px1+4, pTy+4, px1-4, pTy+4);
344 gVirtualX->DrawLine(px1-4, pTy+4, px1-4, pTy-4);
345 gVirtualX->DrawLine(px1-4, pTy-4, px1+4, pTy-4);
346 gVirtualX->DrawLine(px1+4, pTy-4, px1+4, pTy+4);
347 for (i=0;i<npe;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
348 }
349 if (pTop) {
350 sav1 = py1;
351 sav2 = r2;
352 py1 += (py - pyold)/2;
353 r2 -= (py - pyold)/2;
354 if (TMath::Abs(pyold-py)%2==1) impair++;
355 if (py-pyold>0) sig=+1;
356 else sig=-1;
357 if (impair==2) { impair = 0; py1 += sig; r2 -= sig;}
358 if (py1 > pBy-kMinSize) {py1 = sav1; r2 = sav2; py = pyold;}
359 }
360 if (pBot) {
361 sav1 = py1;
362 sav2 = r2;
363 py1 += (py - pyold)/2;
364 r2 += (py - pyold)/2;
365 if (TMath::Abs(pyold-py)%2==1) impair++;
366 if (py-pyold>0) sig=+1;
367 else sig=-1;
368 if (impair==2) { impair = 0; py1 += sig; r2 += sig;}
369 if (py1 < pTy+kMinSize) {py1 = sav1; r2 = sav2; py = pyold;}
370 }
371 if (pL) {
372 sav1 = px1;
373 sav2 = r1;
374 px1 += (px - pxold)/2;
375 r1 -= (px - pxold)/2;
376 if (TMath::Abs(pxold-px)%2==1) impair++;
377 if (px-pxold>0) sig=+1;
378 else sig=-1;
379 if (impair==2) { impair = 0; px1 += sig; r1 -= sig;}
380 if (px1 > pRx-kMinSize) {px1 = sav1; r1 = sav2; px = pxold;}
381 }
382 if (pR) {
383 sav1 = px1;
384 sav2 = r1;
385 px1 += (px - pxold)/2;
386 r1 += (px - pxold)/2;
387 if (TMath::Abs(pxold-px)%2==1) impair++;
388 if (px-pxold>0) sig=+1;
389 else sig=-1;
390 if (impair==2) { impair = 0; px1 += sig; r1 += sig;}
391 if (px1 < pLx+kMinSize) {px1 = sav1; r1 = sav2; px = pxold;}
392 }
393 if (pTop || pBot || pL || pR) {
394 if (!opaque) {
395 dphi = (fPhimax-fPhimin)*kPI/(180*np);
396 ct = TMath::Cos(kPI*fTheta/180);
397 st = TMath::Sin(kPI*fTheta/180);
398 for (i=0;i<np;i++) {
399 angle = fPhimin*kPI/180 + Double_t(i)*dphi;
400 dx = r1*TMath::Cos(angle);
401 dy = r2*TMath::Sin(angle);
402 x[i] = px1 + Int_t(dx*ct - dy*st);
403 y[i] = py1 + Int_t(dx*st + dy*ct);
404 }
405 if (fPhimax-fPhimin >= 360 ) {
406 x[np] = x[0];
407 y[np] = y[0];
408 npe = np;
409 } else {
410 x[np] = px1;
411 y[np] = py1;
412 x[np+1] = x[0];
413 y[np+1] = y[0];
414 npe = np + 1;
415 }
416 gVirtualX->SetLineColor(-1);
418 for (i=0;i<npe;i++)
419 gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
420 }
421 else
422 {
423 this->SetX1(gPad->AbsPixeltoX(px1));
424 this->SetY1(gPad->AbsPixeltoY(py1));
425 this->SetR1(TMath::Abs(gPad->AbsPixeltoX(px1-r1)-gPad->AbsPixeltoX(px1+r1))/2);
426 this->SetR2(TMath::Abs(gPad->AbsPixeltoY(py1-r2)-gPad->AbsPixeltoY(py1+r2))/2);
427 if (pTop) gPad->ShowGuidelines(this, event, 't', true);
428 if (pBot) gPad->ShowGuidelines(this, event, 'b', true);
429 if (pL) gPad->ShowGuidelines(this, event, 'l', true);
430 if (pR) gPad->ShowGuidelines(this, event, 'r', true);
431 gPad->Modified(kTRUE);
432 gPad->Update();
433 }
434 }
435 if (pINSIDE) {
436 if (!opaque){
437 dpx = px-pxold; dpy = py-pyold;
438 px1 += dpx; py1 += dpy;
439 for (i=0;i<=npe;i++) { x[i] += dpx; y[i] += dpy;}
440 for (i=0;i<npe;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
441 }
442 else {
443 this->SetX1(gPad->AbsPixeltoX(px)+sdx);
444 this->SetY1(gPad->AbsPixeltoY(py)+sdy);
445 gPad->ShowGuidelines(this, event, 'i', true);
446 gPad->Modified(kTRUE);
447 gPad->Update();
448 }
449 }
450 if (!opaque){
451 pTx = pBx = px1;
452 pRx = px1+r1;
453 pLx = px1-r1;
454 pRy = pLy = py1;
455 pTy = py1-r2;
456 pBy = py1+r2;
457 gVirtualX->DrawLine(pRx+4, py1+4, pRx-4, py1+4);
458 gVirtualX->DrawLine(pRx-4, py1+4, pRx-4, py1-4);
459 gVirtualX->DrawLine(pRx-4, py1-4, pRx+4, py1-4);
460 gVirtualX->DrawLine(pRx+4, py1-4, pRx+4, py1+4);
461 gVirtualX->DrawLine(pLx+4, py1+4, pLx-4, py1+4);
462 gVirtualX->DrawLine(pLx-4, py1+4, pLx-4, py1-4);
463 gVirtualX->DrawLine(pLx-4, py1-4, pLx+4, py1-4);
464 gVirtualX->DrawLine(pLx+4, py1-4, pLx+4, py1+4);
465 gVirtualX->DrawLine(px1+4, pBy+4, px1-4, pBy+4);
466 gVirtualX->DrawLine(px1-4, pBy+4, px1-4, pBy-4);
467 gVirtualX->DrawLine(px1-4, pBy-4, px1+4, pBy-4);
468 gVirtualX->DrawLine(px1+4, pBy-4, px1+4, pBy+4);
469 gVirtualX->DrawLine(px1+4, pTy+4, px1-4, pTy+4);
470 gVirtualX->DrawLine(px1-4, pTy+4, px1-4, pTy-4);
471 gVirtualX->DrawLine(px1-4, pTy-4, px1+4, pTy-4);
472 gVirtualX->DrawLine(px1+4, pTy-4, px1+4, pTy+4);
473 }
474 pxold = px;
475 pyold = py;
476 break;
477
478 case kButton1Up:
479 if (gROOT->IsEscaped()) {
480 gROOT->SetEscape(kFALSE);
481 if (opaque) {
482 gPad->ShowGuidelines(this, event);
483 this->SetX1(oldX1);
484 this->SetY1(oldY1);
485 this->SetR1(oldR1);
486 this->SetR2(oldR2);
487 gPad->Modified(kTRUE);
488 gPad->Update();
489 }
490 break;
491 }
492
493 if (opaque) {
494 gPad->ShowGuidelines(this, event);
495 } else {
496 fX1 = gPad->AbsPixeltoX(px1);
497 fY1 = gPad->AbsPixeltoY(py1);
498 fBy = gPad->AbsPixeltoY(py1+r2);
499 fTy = gPad->AbsPixeltoY(py1-r2);
500 fLx = gPad->AbsPixeltoX(px1+r1);
501 fRx = gPad->AbsPixeltoX(px1-r1);
502 fR1 = TMath::Abs(fRx-fLx)/2;
503 fR2 = TMath::Abs(fTy-fBy)/2;
504 gPad->Modified(kTRUE);
505 gVirtualX->SetLineColor(-1);
506 }
507 }
508}
509
510////////////////////////////////////////////////////////////////////////////////
511/// Return 1 if the point (x,y) is inside the polygon defined by
512/// the ellipse 0 otherwise.
513/// Author: Ole Hansen (ole@jlab.org)
515{
516 x -= fX1;
517 y -= fY1;
519 Double_t st = TMath::Sin(th);
520 Double_t ct = TMath::Cos(th);
521 Double_t xx = ct * x + st * y;
522 Double_t yy = -st * x + ct * y;
523
524 if (TMath::Abs(xx) > fR1 || TMath::Abs(yy) > fR2)
525 return 0;
526 Double_t xn = xx / fR1;
527 Double_t yn = yy / fR2;
528 if (xn * xn + yn * yn > 1.)
529 return 0;
530 if (fPhimax - fPhimin >= 360.)
531 return 1;
532 Double_t phimin = std::fmod(fPhimin, 360.);
533 Double_t phimax = std::fmod(fPhimax, 360.);
534 Double_t phi = TMath::RadToDeg()*(TMath::Pi() + TMath::ATan2(-yy * fR1 / fR2, -xx));
535 if (phi < phimin || phi > phimax)
536 return 0;
537
538 return 1;
539}
540
541
542////////////////////////////////////////////////////////////////////////////////
543/// List this ellipse with its attributes.
544
545void TEllipse::ls(Option_t *) const
546{
548 printf("%s: X1= %f Y1=%f R1=%f R2=%f\n",GetName(),fX1,fY1,fR1,fR2);
549}
550
551////////////////////////////////////////////////////////////////////////////////
552/// Paint this ellipse with its current attributes.
553
554void TEllipse::Paint(Option_t *option)
555{
557}
558
559////////////////////////////////////////////////////////////////////////////////
560/// Draw this ellipse with new coordinates.
561
563 Double_t phimin, Double_t phimax, Double_t theta,
564 Option_t *option)
565{
566 if (!gPad) return;
567 const Int_t np = 200;
568 static Double_t x[np+3], y[np+3];
569 TAttLine::Modify(); //Change line attributes only if necessary
570 TAttFill::Modify(); //Change fill attributes only if necessary
571
572 Double_t phi1 = TMath::Min(phimin,phimax);
573 Double_t phi2 = TMath::Max(phimin,phimax);
574
575 //set number of points approximatively proportional to the ellipse circumference
576 Double_t circ = kPI*(r1+r2)*(phi2-phi1)/360;
577 Int_t n = (Int_t)(np*circ/((gPad->GetX2()-gPad->GetX1())+(gPad->GetY2()-gPad->GetY1())));
578 if (n < 8) n= 8;
579 if (n > np) n = np;
580 Double_t angle,dx,dy;
581 Double_t dphi = (phi2-phi1)*kPI/(180*n);
582 Double_t ct = TMath::Cos(kPI*theta/180);
583 Double_t st = TMath::Sin(kPI*theta/180);
584 for (Int_t i=0;i<=n;i++) {
585 angle = phi1*kPI/180 + Double_t(i)*dphi;
586 dx = r1*TMath::Cos(angle);
587 dy = r2*TMath::Sin(angle);
588 x[i] = gPad->XtoPad(x1 + dx*ct - dy*st);
589 y[i] = gPad->YtoPad(y1 + dx*st + dy*ct);
590 }
591 TString opt = option;
592 opt.ToLower();
593 if (phi2-phi1 >= 360 ) {
594 if (GetFillStyle()) gPad->PaintFillArea(n,x,y);
595 if (GetLineStyle()) gPad->PaintPolyLine(n+1,x,y);
596 } else {
597 x[n+1] = gPad->XtoPad(x1);
598 y[n+1] = gPad->YtoPad(y1);
599 x[n+2] = x[0];
600 y[n+2] = y[0];
601 if (GetFillStyle()) gPad->PaintFillArea(n+2,x,y);
602 if (GetLineStyle()) {
603 if (TestBit(kNoEdges) || opt.Contains("only")) gPad->PaintPolyLine(n+1,x,y);
604 else gPad->PaintPolyLine(n+3,x,y);
605 }
606 }
607}
608
609////////////////////////////////////////////////////////////////////////////////
610/// Dump this ellipse with its attributes.
611
612void TEllipse::Print(Option_t *) const
613{
614 printf("Ellipse: X1=%f Y1=%f R1=%f R2=%f",fX1,fY1,fR1,fR2);
615 if (GetLineColor() != 1) printf(" Color=%d",GetLineColor());
616 if (GetLineStyle() != 1) printf(" Style=%d",GetLineStyle());
617 if (GetLineWidth() != 1) printf(" Width=%d",GetLineWidth());
618 printf("\n");
619}
620
621////////////////////////////////////////////////////////////////////////////////
622/// Save primitive as a C++ statement(s) on output stream out
623
624void TEllipse::SavePrimitive(std::ostream &out, Option_t *option)
625{
627 out, Class(), "ellipse",
628 TString::Format("%g, %g, %g, %g, %g, %g, %g", fX1, fY1, fR1, fR2, fPhimin, fPhimax, fTheta));
629
630 SaveFillAttributes(out, "ellipse", 0, 1001);
631 SaveLineAttributes(out, "ellipse", 1, 1, 1);
632
633 if (GetNoEdges())
634 out << " ellipse->SetNoEdges();\n";
635
636 SavePrimitiveDraw(out, "ellipse", option);
637}
638
639////////////////////////////////////////////////////////////////////////////////
640/// Return kTRUE if kNoEdges bit is set, kFALSE otherwise.
641
643{
644 return TestBit(kNoEdges) ? kTRUE : kFALSE;
645}
646
647////////////////////////////////////////////////////////////////////////////////
648/// if noEdges = kTRUE the lines connecting the center to the edges
649/// will not be drawn.
650/// default is to draw the edges.
651
652void TEllipse::SetNoEdges(Bool_t noEdges)
653{
654 if (noEdges) SetBit(kNoEdges);
655 else ResetBit(kNoEdges);
656}
657
658////////////////////////////////////////////////////////////////////////////////
659/// Stream an object of class TEllipse.
660
661void TEllipse::Streamer(TBuffer &R__b)
662{
663 if (R__b.IsReading()) {
664 UInt_t R__s, R__c;
665 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
666 if (R__v > 1) {
667 R__b.ReadClassBuffer(TEllipse::Class(), this, R__v, R__s, R__c);
668 return;
669 }
670 //====process old versions before automatic schema evolution
671 TObject::Streamer(R__b);
672 TAttLine::Streamer(R__b);
673 TAttFill::Streamer(R__b);
674 Float_t x1,y1,r1,r2,phimin,phimax,theta;
675 R__b >> x1; fX1 = x1;
676 R__b >> y1; fY1 = y1;
677 R__b >> r1; fR1 = r1;
678 R__b >> r2; fR2 = r2;
679 R__b >> phimin; fPhimin = phimin;
680 R__b >> phimax; fPhimax = phimax;
681 R__b >> theta; fTheta = theta;
682 R__b.CheckByteCount(R__s, R__c, TEllipse::IsA());
683 //====end of old versions
684
685 } else {
687 }
688}
689
690////////////////////////////////////////////////////////////////////////////////
691/// Return the bounding Box of the Ellipse, currently not taking into
692/// account the rotating angle.
693
695{
696 Rectangle_t BBox{0, 0, 0, 0};
697 if (gPad) {
698 BBox.fX = gPad->XtoPixel(fX1 - fR1);
699 BBox.fY = gPad->YtoPixel(fY1 + fR2);
700 BBox.fWidth = gPad->XtoPixel(fX1 + fR1) - gPad->XtoPixel(fX1 - fR1);
701 BBox.fHeight = gPad->YtoPixel(fY1 - fR2) - gPad->YtoPixel(fY1 + fR2);
702 }
703 return BBox;
704}
705
706////////////////////////////////////////////////////////////////////////////////
707/// Return the center of the Ellipse as TPoint in pixels
708
710{
711 TPoint p(0, 0);
712 if (gPad) {
713 p.SetX(gPad->XtoPixel(fX1));
714 p.SetY(gPad->YtoPixel(fY1));
715 }
716 return p;
717}
718
719////////////////////////////////////////////////////////////////////////////////
720/// Set center of the Ellipse
721
722void TEllipse::SetBBoxCenter(const TPoint &p)
723{
724 if (!gPad) return;
725 fX1 = gPad->PixeltoX(p.GetX());
726 fY1 = gPad->PixeltoY(p.GetY()-gPad->VtoPixel(0));
727}
728
729////////////////////////////////////////////////////////////////////////////////
730/// Set X coordinate of the center of the Ellipse
731
733{
734 if (!gPad) return;
735 fX1 = gPad->PixeltoX(x);
736}
737
738////////////////////////////////////////////////////////////////////////////////
739/// Set Y coordinate of the center of the Ellipse
740
742{
743 if (!gPad) return;
744 fY1 = gPad->PixeltoY(y-gPad->VtoPixel(0));
745}
746
747////////////////////////////////////////////////////////////////////////////////
748/// Set left hand side of BoundingBox to a value
749/// (resize in x direction on left)
750
751void TEllipse::SetBBoxX1(const Int_t x)
752{
753 if (!gPad) return;
754 Double_t x1 = gPad->PixeltoX(x);
755 if (x1>fX1+fR1) return;
756
757 fR1 = (fX1+fR1-x1)*0.5;
758 fX1 = x1 + fR1;
759}
760
761////////////////////////////////////////////////////////////////////////////////
762/// Set right hand side of BoundingBox to a value
763/// (resize in x direction on right)
764
765void TEllipse::SetBBoxX2(const Int_t x)
766{
767 if (!gPad) return;
768 Double_t x2 = gPad->PixeltoX(x);
769 if (x2<fX1-fR1) return;
770
771 fR1 = (x2-fX1+fR1)*0.5;
772 fX1 = x2-fR1;
773}
774
775////////////////////////////////////////////////////////////////////////////////
776/// Set top of BoundingBox to a value (resize in y direction on top)
777
778void TEllipse::SetBBoxY1(const Int_t y)
779{
780 if (!gPad) return;
781 Double_t y1 = gPad->PixeltoY(y-gPad->VtoPixel(0));
782 if (y1<fY1-fR2) return;
783
784 fR2 = (y1-fY1+fR2)*0.5;
785 fY1 = y1-fR2;
786}
787
788////////////////////////////////////////////////////////////////////////////////
789/// Set bottom of BoundingBox to a value
790/// (resize in y direction on bottom)
791
792void TEllipse::SetBBoxY2(const Int_t y)
793{
794 if (!gPad) return;
795 Double_t y2 = gPad->PixeltoY(y-gPad->VtoPixel(0));
796
797 if (y2>fY1+fR2) return;
798
799 fR2 = (fY1+fR2-y2)*0.5;
800 fY1 = y2+fR2;
801}
@ kMouseMotion
Definition Buttons.h:23
@ kArrowKeyRelease
Definition Buttons.h:21
@ kButton1Motion
Definition Buttons.h:20
@ kButton1Up
Definition Buttons.h:19
@ kArrowKeyPress
Definition Buttons.h:21
@ kButton1Down
Definition Buttons.h:17
@ kRightSide
Definition GuiTypes.h:374
@ kBottomSide
Definition GuiTypes.h:374
@ kTopSide
Definition GuiTypes.h:374
@ kLeftSide
Definition GuiTypes.h:374
@ kMove
Definition GuiTypes.h:375
int Int_t
Signed integer 4 bytes (int).
Definition RtypesCore.h:59
short Version_t
Class version identifier (short).
Definition RtypesCore.h:79
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int).
Definition RtypesCore.h:60
bool Bool_t
Boolean (0=false, 1=true) (bool).
Definition RtypesCore.h:77
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
float Float_t
Float 4 bytes (float).
Definition RtypesCore.h:71
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char).
Definition RtypesCore.h:80
constexpr Double_t kPI
Definition TEllipse.cxx:24
#define gROOT
Definition TROOT.h:417
#define gPad
#define gVirtualX
Definition TVirtualX.h:375
Abstract base class for elements drawn in the editor.
Definition TAttBBox2D.h:19
virtual void Streamer(TBuffer &)
virtual Color_t GetFillColor() const
Return the fill area color.
Definition TAttFill.h:32
void Copy(TAttFill &attfill) const
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition TAttFill.h:33
virtual void Modify()
virtual void SaveFillAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1001)
virtual void Streamer(TBuffer &)
virtual Color_t GetLineColor() const
Return the line color.
Definition TAttLine.h:36
virtual void Modify()
virtual Width_t GetLineWidth() const
Return the line width.
Definition TAttLine.h:38
virtual void SaveLineAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1, Int_t widdef=1)
virtual Style_t GetLineStyle() const
Return the line style.
Definition TAttLine.h:37
void Copy(TAttLine &attline) const
Buffer base class used for serializing objects.
Definition TBuffer.h:43
virtual Version_t ReadVersion(UInt_t *start=nullptr, UInt_t *bcnt=nullptr, const TClass *cl=nullptr)=0
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=nullptr)=0
Bool_t IsReading() const
Definition TBuffer.h:86
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
TClass * IsA() const override
Definition TEllipse.h:80
virtual void SetR1(Double_t r1)
Definition TEllipse.h:65
void ls(Option_t *option="") const override
The ls function lists the contents of a class on stdout.
virtual void SetX1(Double_t x1)
Definition TEllipse.h:68
void SetBBoxCenterY(const Int_t y) override
Double_t GetTheta() const
Definition TEllipse.h:55
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
Execute action corresponding to an event at (px,py).
void SetBBoxY1(const Int_t y) override
void SetBBoxX1(const Int_t x) override
void SetBBoxY2(const Int_t y) override
Double_t GetX1() const
Definition TEllipse.h:49
Double_t fPhimax
Maximum angle (degrees).
Definition TEllipse.h:31
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
Computes distance from point (px,py) to the object.
virtual void PaintEllipse(Double_t x1, Double_t y1, Double_t r1, Double_t r2, Double_t phimin, Double_t phimax, Double_t theta, Option_t *option="")
Double_t fX1
X coordinate of centre.
Definition TEllipse.h:26
void SetBBoxX2(const Int_t x) override
Bool_t GetNoEdges() const
void Draw(Option_t *option="") override
Default Draw method for all objects.
Rectangle_t GetBBox() override
void Paint(Option_t *option="") override
This method must be overridden if a class wants to paint itself.
Double_t fY1
Y coordinate of centre.
Definition TEllipse.h:27
Double_t fTheta
Rotation angle (degrees).
Definition TEllipse.h:32
void SetBBoxCenter(const TPoint &p) override
Int_t IsInside(Double_t x, Double_t y) const
void SetBBoxCenterX(const Int_t x) override
virtual 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="")
virtual void SetY1(Double_t y1)
Definition TEllipse.h:69
~TEllipse() override
@ kNoEdges
Definition TEllipse.h:37
Double_t fR2
second radius
Definition TEllipse.h:29
void Streamer(TBuffer &) override
Stream an object of class TObject.
void Copy(TObject &ellipse) const override
Copy this to obj.
Double_t fPhimin
Minimum angle (degrees).
Definition TEllipse.h:30
virtual void SetNoEdges(Bool_t noEdges=kTRUE)
Double_t GetY1() const
Definition TEllipse.h:50
TPoint GetBBoxCenter() override
Double_t fR1
first radius
Definition TEllipse.h:28
static TClass * Class()
virtual void SetR2(Double_t r2)
Definition TEllipse.h:66
void Print(Option_t *option="") const override
This method must be overridden when a class wants to print itself.
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save a primitive as a C++ statement(s) on output stream "out".
Mother of all ROOT objects.
Definition TObject.h:42
Bool_t TestBit(UInt_t f) const
Definition TObject.h:204
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:462
virtual void Streamer(TBuffer &)
Stream an object of class TObject.
Definition TObject.cxx:997
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition TObject.cxx:204
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:888
virtual void Copy(TObject &object) const
Copy this to obj.
Definition TObject.cxx:159
static void SavePrimitiveDraw(std::ostream &out, const char *variable_name, Option_t *option=nullptr)
Save invocation of primitive Draw() method Skipped if option contains "nodraw" string.
Definition TObject.cxx:845
static void SavePrimitiveConstructor(std::ostream &out, TClass *cl, const char *variable_name, const char *constructor_agrs="", Bool_t empty_line=kTRUE)
Save object constructor in the output stream "out".
Definition TObject.cxx:777
void ResetBit(UInt_t f)
Definition TObject.h:203
@ kCanDelete
if object in a list can be deleted
Definition TObject.h:71
SCoord_t GetY() const
Definition TPoint.h:47
SCoord_t GetX() const
Definition TPoint.h:46
static void IndentLevel()
Functions used by ls() to indent an object hierarchy.
Definition TROOT.cxx:3052
void ToLower()
Change string to lower-case.
Definition TString.cxx:1189
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2385
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:641
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)
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:249
Double_t ATan2(Double_t y, Double_t x)
Returns the principal value of the arc tangent of y/x, expressed in radians.
Definition TMath.h:657
constexpr Double_t DegToRad()
Conversion from degree to radian: .
Definition TMath.h:82
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:673
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:197
Double_t Cos(Double_t)
Returns the cosine of an angle of x radians.
Definition TMath.h:605
constexpr Double_t Pi()
Definition TMath.h:40
Double_t Sin(Double_t)
Returns the sine of an angle of x radians.
Definition TMath.h:599
constexpr Double_t RadToDeg()
Conversion from radian to degree: .
Definition TMath.h:75
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:122
Rectangle structure (maps to the X11 XRectangle structure).
Definition GuiTypes.h:362
Short_t fX
Definition GuiTypes.h:363
UShort_t fHeight
Definition GuiTypes.h:364
Short_t fY
Definition GuiTypes.h:363
UShort_t fWidth
Definition GuiTypes.h:364