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
27
28/** \class TEllipse
29\ingroup BasicGraphics
30
31Draw Ellipses.
32
33The ellipse can be truncated and rotated. It is defined by its center `(x1,y1)`
34and two radius `r1` and `r2`.
35
36A minimum and maximum angle may be specified `(phimin, phimax)`.
37The ellipse may be rotated with an angle `theta`. All these
38angles are in degrees.
39The attributes of the outline line are given via `TAttLine`.
40The attributes of the fill area are given via `TAttFill`.
41The picture below illustrates different types of ellipses.
42
43When an ellipse sector only is drawn, the lines connecting the center
44of the ellipse to the edges are drawn by default. One can specify
45the drawing option "only" to not draw these lines or alternatively
46call the function `SetNoEdges()`. To remove completely the ellipse
47outline it is enough to specify 0 as line style.
48
49Begin_Macro(source)
50../../../tutorials/graphics/ellipse.C
51End_Macro
52*/
53
54////////////////////////////////////////////////////////////////////////////////
55/// Ellipse default constructor.
56
58{
59 fX1 = 0;
60 fY1 = 0;
61 fR1 = 1;
62 fR2 = 1;
63 fPhimin = 0;
64 fPhimax = 360;
65 fTheta = 0;
66}
67
68////////////////////////////////////////////////////////////////////////////////
69/// Ellipse normal constructor.
70
72 :TObject(), TAttLine(), TAttFill(0,1001)
73{
74 fX1 = x1;
75 fY1 = y1;
76 fR1 = r1;
77 fR2 = r2;
78 fPhimin = phimin;
79 fPhimax = phimax;
80 fTheta = theta;
81 if (r2 <= 0) fR2 = fR1;
82}
83
84////////////////////////////////////////////////////////////////////////////////
85/// Ellipse default destructor.
86
88{
89}
90
91////////////////////////////////////////////////////////////////////////////////
92/// Copy constructor.
93
94TEllipse::TEllipse(const TEllipse &ellipse) : TObject(ellipse), TAttLine(ellipse), TAttFill(ellipse), TAttBBox2D(ellipse)
95{
96 fX1 = 0;
97 fY1 = 0;
98 fR1 = 1;
99 fR2 = 1;
100 fPhimin = 0;
101 fPhimax = 360;
102 fTheta = 0;
103
104 ellipse.TEllipse::Copy(*this);
105}
106
107////////////////////////////////////////////////////////////////////////////////
108/// Copy this ellipse to ellipse.
109
110void TEllipse::Copy(TObject &obj) const
111{
112 TObject::Copy(obj);
113 TAttLine::Copy(((TEllipse&)obj));
114 TAttFill::Copy(((TEllipse&)obj));
115 ((TEllipse&)obj).fX1 = fX1;
116 ((TEllipse&)obj).fY1 = fY1;
117 ((TEllipse&)obj).fR1 = fR1;
118 ((TEllipse&)obj).fR2 = fR2;
119 ((TEllipse&)obj).fPhimin = fPhimin;
120 ((TEllipse&)obj).fPhimax = fPhimax;
121 ((TEllipse&)obj).fTheta = fTheta;
122}
123
124////////////////////////////////////////////////////////////////////////////////
125/// Compute distance from point px,py to an ellipse.
126///
127/// Compute the closest distance of approach from point px,py to this
128/// ellipse. The distance is computed in pixels units.
129///
130/// In case of a filled ellipse the distance returned is 0 if the point
131/// (px,py) is inside the ellipse, and is huge if the point is outside.
132
134{
135 if (!gPad) return 9999;
136 Double_t x = gPad->PadtoX(gPad->AbsPixeltoX(px));
137 Double_t y = gPad->PadtoY(gPad->AbsPixeltoY(py));
138
139 Double_t dxnr = x - fX1;
140 Double_t dynr = y - fY1;
141
142 Double_t ct = TMath::Cos(kPI*GetTheta()/180.0);
143 Double_t st = TMath::Sin(kPI*GetTheta()/180.0);
144
145 Double_t dx = dxnr*ct + dynr*st;
146 Double_t dy = -dxnr*st + dynr*ct;
147
148 Double_t r1 = fR1;
149 Double_t r2 = fR2;
150
151 if (dx == 0 || r1 == 0 || r2 == 0) return 9999;
152 Double_t distp = TMath::Sqrt(dx*dx + dy*dy);
153
154 Double_t tana = dy/dx;
155 tana *= tana;
156 Double_t distr = TMath::Sqrt((1+tana)/(1.0/(r1*r1) + tana/(r2*r2)));
157 Int_t dist = 9999;
158 if (GetFillColor() && GetFillStyle()) {
159 if (distr > distp) dist = 0;
160 } else {
161 if (TMath::Abs(distr-distp)/(r1+r2) < 0.01) dist = 0;
162 }
163 return dist;
164}
165
166////////////////////////////////////////////////////////////////////////////////
167/// Draw this ellipse with its current attributes.
168
170{
172}
173
174////////////////////////////////////////////////////////////////////////////////
175/// Draw this ellipse with new coordinates.
176
178{
179 TEllipse *newellipse = new TEllipse(x1, y1, r1, r2, phimin, phimax,theta);
180 TAttLine::Copy(*newellipse);
181 TAttFill::Copy(*newellipse);
182 newellipse->SetBit(kCanDelete);
183 newellipse->AppendPad(option);
184 if (TestBit(kNoEdges)) newellipse->SetBit(kNoEdges);
185 return newellipse;
186}
187
188////////////////////////////////////////////////////////////////////////////////
189/// Execute action corresponding to one event.
190///
191/// This member function is called when a line is clicked with the locator
192///
193/// If Left button clicked on one of the line end points, this point
194/// follows the cursor until button is released.
195///
196/// if Middle button clicked, the line is moved parallel to itself
197/// until the button is released.
198///
199/// NOTE that support for log scale is not implemented
200
202{
203 if (!gPad) return;
204
205 Int_t kMaxDiff = 10;
206
207 Int_t i, dpx, dpy;
208 Double_t angle,dx,dy,dphi,ct,st,fTy,fBy,fLx,fRx;
209 static Int_t px1,py1,npe,r1,r2,sav1,sav2;
210 const Int_t kMinSize = 25;
211 const Int_t np = 40;
212 static Bool_t pTop, pL, pR, pBot, pINSIDE;
213 static Int_t pTx,pTy,pLx,pLy,pRx,pRy,pBx,pBy;
214 static Int_t x[np+2], y[np+2];
215 static Int_t pxold, pyold;
216 static Int_t sig,impair;
217 static Double_t sdx, sdy;
218 static Double_t oldX1, oldY1, oldR1, oldR2;
219
220 Bool_t opaque = gPad->OpaqueMoving();
221
222 if (!gPad->IsEditable()) return;
223
224 switch (event) {
225
226 case kArrowKeyPress:
227 case kButton1Down:
228 oldX1 = fX1;
229 oldY1 = fY1;
230 oldR1 = fR1;
231 oldR2 = fR2;
232 dphi = (fPhimax-fPhimin)*kPI/(180*np);
233 ct = TMath::Cos(kPI*fTheta/180);
234 st = TMath::Sin(kPI*fTheta/180);
235 for (i=0;i<np;i++) {
236 angle = fPhimin*kPI/180 + Double_t(i)*dphi;
237 dx = fR1*TMath::Cos(angle);
238 dy = fR2*TMath::Sin(angle);
239 x[i] = gPad->XtoAbsPixel(fX1 + dx*ct - dy*st);
240 y[i] = gPad->YtoAbsPixel(fY1 + dx*st + dy*ct);
241 }
242 if (fPhimax-fPhimin >= 360 ) {
243 x[np] = x[0];
244 y[np] = y[0];
245 npe = np;
246 } else {
247 x[np] = gPad->XtoAbsPixel(fX1);
248 y[np] = gPad->YtoAbsPixel(fY1);
249 x[np+1] = x[0];
250 y[np+1] = y[0];
251 npe = np + 1;
252 }
253 impair = 0;
254 px1 = gPad->XtoAbsPixel(fX1);
255 py1 = gPad->YtoAbsPixel(fY1);
256 pTx = pBx = px1;
257 pLy = pRy = py1;
258 pTy = gPad->YtoAbsPixel(fR2+fY1);
259 pBy = gPad->YtoAbsPixel(-fR2+fY1);
260 pLx = gPad->XtoAbsPixel(-fR1+fX1);
261 pRx = gPad->XtoAbsPixel(fR1+fX1);
262 r2 = (pBy-pTy)/2;
263 r1 = (pRx-pLx)/2;
264 if (!opaque) {
265 gVirtualX->SetLineColor(-1);
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(pRx+4, py1-4, pRx+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(pLx+4, py1-4, pLx+4, py1+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, pBy-4, px1+4, pBy+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 gVirtualX->DrawLine(px1+4, pTy-4, px1+4, pTy+4);
283 }
284 else {
285 sdx = this->GetX1()-gPad->AbsPixeltoX(px);
286 sdy = this->GetY1()-gPad->AbsPixeltoY(py);
287 }
288 // No break !!!
289
290 case kMouseMotion:
291 px1 = gPad->XtoAbsPixel(fX1);
292 py1 = gPad->YtoAbsPixel(fY1);
293 pTx = pBx = px1;
294 pLy = pRy = py1;
295 pTy = gPad->YtoAbsPixel(fR2+fY1);
296 pBy = gPad->YtoAbsPixel(-fR2+fY1);
297 pLx = gPad->XtoAbsPixel(-fR1+fX1);
298 pRx = gPad->XtoAbsPixel(fR1+fX1);
299 pTop = pL = pR = pBot = pINSIDE = kFALSE;
300 if ((TMath::Abs(px - pTx) < kMaxDiff) &&
301 (TMath::Abs(py - pTy) < kMaxDiff)) { // top edge
302 pTop = kTRUE;
303 gPad->SetCursor(kTopSide);
304 }
305 else
306 if ((TMath::Abs(px - pBx) < kMaxDiff) &&
307 (TMath::Abs(py - pBy) < kMaxDiff)) { // bottom edge
308 pBot = kTRUE;
309 gPad->SetCursor(kBottomSide);
310 }
311 else
312 if ((TMath::Abs(py - pLy) < kMaxDiff) &&
313 (TMath::Abs(px - pLx) < kMaxDiff)) { // left edge
314 pL = kTRUE;
315 gPad->SetCursor(kLeftSide);
316 }
317 else
318 if ((TMath::Abs(py - pRy) < kMaxDiff) &&
319 (TMath::Abs(px - pRx) < kMaxDiff)) { // right edge
320 pR = kTRUE;
321 gPad->SetCursor(kRightSide);
322 }
323 else {pINSIDE= kTRUE; gPad->SetCursor(kMove); }
324 pxold = px; pyold = py;
325
326 break;
327
328 case kArrowKeyRelease:
329 case kButton1Motion:
330 if (!opaque)
331 {
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(pRx+4, py1-4, pRx+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(pLx+4, py1-4, pLx+4, py1+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, pBy-4, px1+4, pBy+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 gVirtualX->DrawLine(px1+4, pTy-4, px1+4, pTy+4);
348 for (i=0;i<npe;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
349 }
350 if (pTop) {
351 sav1 = py1;
352 sav2 = r2;
353 py1 += (py - pyold)/2;
354 r2 -= (py - pyold)/2;
355 if (TMath::Abs(pyold-py)%2==1) impair++;
356 if (py-pyold>0) sig=+1;
357 else sig=-1;
358 if (impair==2) { impair = 0; py1 += sig; r2 -= sig;}
359 if (py1 > pBy-kMinSize) {py1 = sav1; r2 = sav2; py = pyold;}
360 }
361 if (pBot) {
362 sav1 = py1;
363 sav2 = r2;
364 py1 += (py - pyold)/2;
365 r2 += (py - pyold)/2;
366 if (TMath::Abs(pyold-py)%2==1) impair++;
367 if (py-pyold>0) sig=+1;
368 else sig=-1;
369 if (impair==2) { impair = 0; py1 += sig; r2 += sig;}
370 if (py1 < pTy+kMinSize) {py1 = sav1; r2 = sav2; py = pyold;}
371 }
372 if (pL) {
373 sav1 = px1;
374 sav2 = r1;
375 px1 += (px - pxold)/2;
376 r1 -= (px - pxold)/2;
377 if (TMath::Abs(pxold-px)%2==1) impair++;
378 if (px-pxold>0) sig=+1;
379 else sig=-1;
380 if (impair==2) { impair = 0; px1 += sig; r1 -= sig;}
381 if (px1 > pRx-kMinSize) {px1 = sav1; r1 = sav2; px = pxold;}
382 }
383 if (pR) {
384 sav1 = px1;
385 sav2 = r1;
386 px1 += (px - pxold)/2;
387 r1 += (px - pxold)/2;
388 if (TMath::Abs(pxold-px)%2==1) impair++;
389 if (px-pxold>0) sig=+1;
390 else sig=-1;
391 if (impair==2) { impair = 0; px1 += sig; r1 += sig;}
392 if (px1 < pLx+kMinSize) {px1 = sav1; r1 = sav2; px = pxold;}
393 }
394 if (pTop || pBot || pL || pR) {
395 if (!opaque) {
396 dphi = (fPhimax-fPhimin)*kPI/(180*np);
397 ct = TMath::Cos(kPI*fTheta/180);
398 st = TMath::Sin(kPI*fTheta/180);
399 for (i=0;i<np;i++) {
400 angle = fPhimin*kPI/180 + Double_t(i)*dphi;
401 dx = r1*TMath::Cos(angle);
402 dy = r2*TMath::Sin(angle);
403 x[i] = px1 + Int_t(dx*ct - dy*st);
404 y[i] = py1 + Int_t(dx*st + dy*ct);
405 }
406 if (fPhimax-fPhimin >= 360 ) {
407 x[np] = x[0];
408 y[np] = y[0];
409 npe = np;
410 } else {
411 x[np] = px1;
412 y[np] = py1;
413 x[np+1] = x[0];
414 y[np+1] = y[0];
415 npe = np + 1;
416 }
417 gVirtualX->SetLineColor(-1);
419 for (i=0;i<npe;i++)
420 gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
421 }
422 else
423 {
424 this->SetX1(gPad->AbsPixeltoX(px1));
425 this->SetY1(gPad->AbsPixeltoY(py1));
426 this->SetR1(TMath::Abs(gPad->AbsPixeltoX(px1-r1)-gPad->AbsPixeltoX(px1+r1))/2);
427 this->SetR2(TMath::Abs(gPad->AbsPixeltoY(py1-r2)-gPad->AbsPixeltoY(py1+r2))/2);
428 if (pTop) gPad->ShowGuidelines(this, event, 't', true);
429 if (pBot) gPad->ShowGuidelines(this, event, 'b', true);
430 if (pL) gPad->ShowGuidelines(this, event, 'l', true);
431 if (pR) gPad->ShowGuidelines(this, event, 'r', true);
432 gPad->Modified(kTRUE);
433 gPad->Update();
434 }
435 }
436 if (pINSIDE) {
437 if (!opaque){
438 dpx = px-pxold; dpy = py-pyold;
439 px1 += dpx; py1 += dpy;
440 for (i=0;i<=npe;i++) { x[i] += dpx; y[i] += dpy;}
441 for (i=0;i<npe;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
442 }
443 else {
444 this->SetX1(gPad->AbsPixeltoX(px)+sdx);
445 this->SetY1(gPad->AbsPixeltoY(py)+sdy);
446 gPad->ShowGuidelines(this, event, 'i', true);
447 gPad->Modified(kTRUE);
448 gPad->Update();
449 }
450 }
451 if (!opaque){
452 pTx = pBx = px1;
453 pRx = px1+r1;
454 pLx = px1-r1;
455 pRy = pLy = py1;
456 pTy = py1-r2;
457 pBy = py1+r2;
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(pRx+4, py1-4, pRx+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(pLx+4, py1-4, pLx+4, py1+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, pBy-4, px1+4, pBy+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 gVirtualX->DrawLine(px1+4, pTy-4, px1+4, pTy+4);
474 }
475 pxold = px;
476 pyold = py;
477 break;
478
479 case kButton1Up:
480 if (gROOT->IsEscaped()) {
481 gROOT->SetEscape(kFALSE);
482 if (opaque) {
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
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
555{
557}
558
559////////////////////////////////////////////////////////////////////////////////
560/// Draw this ellipse with new coordinates.
561
563 Double_t phimin, Double_t phimax, Double_t theta,
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
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 * /*= ""*/)
625{
626 out<<" "<<std::endl;
627 if (gROOT->ClassSaved(TEllipse::Class())) {
628 out<<" ";
629 } else {
630 out<<" TEllipse *";
631 }
632 out<<"ellipse = new TEllipse("<<fX1<<","<<fY1<<","<<fR1<<","<<fR2
633 <<","<<fPhimin<<","<<fPhimax<<","<<fTheta<<");"<<std::endl;
634
635 SaveFillAttributes(out,"ellipse",0,1001);
636 SaveLineAttributes(out,"ellipse",1,1,1);
637
638 if (GetNoEdges()) out<<" ellipse->SetNoEdges();"<<std::endl;
639
640 out<<" ellipse->Draw();"<<std::endl;
641}
642
643////////////////////////////////////////////////////////////////////////////////
644/// Return kTRUE if kNoEdges bit is set, kFALSE otherwise.
645
647{
648 return TestBit(kNoEdges) ? kTRUE : kFALSE;
649}
650
651////////////////////////////////////////////////////////////////////////////////
652/// if noEdges = kTRUE the lines connecting the center to the edges
653/// will not be drawn.
654/// default is to draw the edges.
655
657{
658 if (noEdges) SetBit(kNoEdges);
659 else ResetBit(kNoEdges);
660}
661
662////////////////////////////////////////////////////////////////////////////////
663/// Stream an object of class TEllipse.
664
666{
667 if (R__b.IsReading()) {
668 UInt_t R__s, R__c;
669 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
670 if (R__v > 1) {
671 R__b.ReadClassBuffer(TEllipse::Class(), this, R__v, R__s, R__c);
672 return;
673 }
674 //====process old versions before automatic schema evolution
675 TObject::Streamer(R__b);
676 TAttLine::Streamer(R__b);
677 TAttFill::Streamer(R__b);
678 Float_t x1,y1,r1,r2,phimin,phimax,theta;
679 R__b >> x1; fX1 = x1;
680 R__b >> y1; fY1 = y1;
681 R__b >> r1; fR1 = r1;
682 R__b >> r2; fR2 = r2;
683 R__b >> phimin; fPhimin = phimin;
684 R__b >> phimax; fPhimax = phimax;
685 R__b >> theta; fTheta = theta;
686 R__b.CheckByteCount(R__s, R__c, TEllipse::IsA());
687 //====end of old versions
688
689 } else {
691 }
692}
693
694////////////////////////////////////////////////////////////////////////////////
695/// Return the bounding Box of the Ellipse, currently not taking into
696/// account the rotating angle.
697
699{
700 Rectangle_t BBox{0,0,0,0};
701 if (!gPad) return BBox;
702 if (!gPad) return (BBox);
703 BBox.fX = gPad->XtoPixel(fX1-fR1);
704 BBox.fY = gPad->YtoPixel(fY1+fR2);
705 BBox.fWidth = gPad->XtoPixel(fX1+fR1)-gPad->XtoPixel(fX1-fR1);
706 BBox.fHeight = gPad->YtoPixel(fY1-fR2)-gPad->YtoPixel(fY1+fR2);
707 return (BBox);
708}
709
710////////////////////////////////////////////////////////////////////////////////
711/// Return the center of the Ellipse as TPoint in pixels
712
714{
715 TPoint p(0,0);
716 if (!gPad) return (p);
717 if (!gPad) return (p);
718 p.SetX(gPad->XtoPixel(fX1));
719 p.SetY(gPad->YtoPixel(fY1));
720 return(p);
721}
722
723////////////////////////////////////////////////////////////////////////////////
724/// Set center of the Ellipse
725
727{
728 if (!gPad) return;
729 fX1 = gPad->PixeltoX(p.GetX());
730 fY1 = gPad->PixeltoY(p.GetY()-gPad->VtoPixel(0));
731}
732
733////////////////////////////////////////////////////////////////////////////////
734/// Set X coordinate of the center of the Ellipse
735
737{
738 if (!gPad) return;
739 fX1 = gPad->PixeltoX(x);
740}
741
742////////////////////////////////////////////////////////////////////////////////
743/// Set Y coordinate of the center of the Ellipse
744
746{
747 if (!gPad) return;
748 fY1 = gPad->PixeltoY(y-gPad->VtoPixel(0));
749}
750
751////////////////////////////////////////////////////////////////////////////////
752/// Set left hand side of BoundingBox to a value
753/// (resize in x direction on left)
754
756{
757 if (!gPad) return;
758 Double_t x1 = gPad->PixeltoX(x);
759 if (x1>fX1+fR1) return;
760
761 fR1 = (fX1+fR1-x1)*0.5;
762 fX1 = x1 + fR1;
763}
764
765////////////////////////////////////////////////////////////////////////////////
766/// Set right hand side of BoundingBox to a value
767/// (resize in x direction on right)
768
770{
771 if (!gPad) return;
772 Double_t x2 = gPad->PixeltoX(x);
773 if (x2<fX1-fR1) return;
774
775 fR1 = (x2-fX1+fR1)*0.5;
776 fX1 = x2-fR1;
777}
778
779////////////////////////////////////////////////////////////////////////////////
780/// Set top of BoundingBox to a value (resize in y direction on top)
781
783{
784 if (!gPad) return;
785 Double_t y1 = gPad->PixeltoY(y-gPad->VtoPixel(0));
786 if (y1<fY1-fR2) return;
787
788 fR2 = (y1-fY1+fR2)*0.5;
789 fY1 = y1-fR2;
790}
791
792////////////////////////////////////////////////////////////////////////////////
793/// Set bottom of BoundingBox to a value
794/// (resize in y direction on bottom)
795
797{
798 if (!gPad) return;
799 Double_t y2 = gPad->PixeltoY(y-gPad->VtoPixel(0));
800
801 if (y2>fY1+fR2) return;
802
803 fR2 = (fY1+fR2-y2)*0.5;
804 fY1 = y2+fR2;
805}
@ 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:373
@ kBottomSide
Definition GuiTypes.h:373
@ kTopSide
Definition GuiTypes.h:373
@ kLeftSide
Definition GuiTypes.h:373
@ kMove
Definition GuiTypes.h:374
int Int_t
Definition RtypesCore.h:45
short Version_t
Definition RtypesCore.h:65
float Float_t
Definition RtypesCore.h:57
constexpr Bool_t kFALSE
Definition RtypesCore.h:101
double Double_t
Definition RtypesCore.h:59
constexpr Bool_t kTRUE
Definition RtypesCore.h:100
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:377
constexpr Double_t kPI
Definition TEllipse.cxx:24
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t option
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 x2
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint TPoint angle
Option_t Option_t TPoint TPoint const char y2
Option_t Option_t TPoint TPoint const char y1
#define gROOT
Definition TROOT.h:406
#define gPad
#define gVirtualX
Definition TVirtualX.h:337
Abstract base class for elements drawn in the editor.
Definition TAttBBox2D.h:19
Fill Area Attributes class.
Definition TAttFill.h:19
virtual void Streamer(TBuffer &)
virtual Color_t GetFillColor() const
Return the fill area color.
Definition TAttFill.h:30
void Copy(TAttFill &attfill) const
Copy this fill attributes to a new TAttFill.
Definition TAttFill.cxx:207
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition TAttFill.h:31
virtual void Modify()
Change current fill area attributes if necessary.
Definition TAttFill.cxx:216
virtual void SaveFillAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1001)
Save fill attributes as C++ statement(s) on output stream out.
Definition TAttFill.cxx:239
Line Attributes class.
Definition TAttLine.h:18
virtual void Streamer(TBuffer &)
virtual Color_t GetLineColor() const
Return the line color.
Definition TAttLine.h:33
virtual Width_t GetLineWidth() const
Return the line width.
Definition TAttLine.h:35
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:247
void Copy(TAttLine &attline) const
Copy this line attributes to a new TAttLine.
Definition TAttLine.cxx:177
virtual void SaveLineAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1, Int_t widdef=1)
Save line attributes as C++ statement(s) on output stream out.
Definition TAttLine.cxx:275
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
Draw Ellipses.
Definition TEllipse.h:23
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
List this ellipse with its attributes.
Definition TEllipse.cxx:545
virtual void SetX1(Double_t x1)
Definition TEllipse.h:68
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="")
Draw this ellipse with new coordinates.
Definition TEllipse.cxx:562
void SetBBoxCenterY(const Int_t y) override
Set Y coordinate of the center of the Ellipse.
Definition TEllipse.cxx:745
Double_t GetTheta() const
Definition TEllipse.h:55
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
Execute action corresponding to one event.
Definition TEllipse.cxx:201
void SetBBoxY1(const Int_t y) override
Set top of BoundingBox to a value (resize in y direction on top)
Definition TEllipse.cxx:782
void SetBBoxX1(const Int_t x) override
Set left hand side of BoundingBox to a value (resize in x direction on left)
Definition TEllipse.cxx:755
void SetBBoxY2(const Int_t y) override
Set bottom of BoundingBox to a value (resize in y direction on bottom)
Definition TEllipse.cxx:796
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
Compute distance from point px,py to an ellipse.
Definition TEllipse.cxx:133
Double_t fX1
X coordinate of centre.
Definition TEllipse.h:26
void SetBBoxX2(const Int_t x) override
Set right hand side of BoundingBox to a value (resize in x direction on right)
Definition TEllipse.cxx:769
Bool_t GetNoEdges() const
Return kTRUE if kNoEdges bit is set, kFALSE otherwise.
Definition TEllipse.cxx:646
void Draw(Option_t *option="") override
Draw this ellipse with its current attributes.
Definition TEllipse.cxx:169
Rectangle_t GetBBox() override
Return the bounding Box of the Ellipse, currently not taking into account the rotating angle.
Definition TEllipse.cxx:698
void Paint(Option_t *option="") override
Paint this ellipse with its current attributes.
Definition TEllipse.cxx:554
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
Set center of the Ellipse.
Definition TEllipse.cxx:726
Int_t IsInside(Double_t x, Double_t y) const
Return 1 if the point (x,y) is inside the polygon defined by the ellipse 0 otherwise.
Definition TEllipse.cxx:514
void SetBBoxCenterX(const Int_t x) override
Set X coordinate of the center of the Ellipse.
Definition TEllipse.cxx:736
virtual void SetY1(Double_t y1)
Definition TEllipse.h:69
~TEllipse() override
Ellipse default destructor.
Definition TEllipse.cxx:87
Double_t fR2
second radius
Definition TEllipse.h:29
void Streamer(TBuffer &) override
Stream an object of class TEllipse.
Definition TEllipse.cxx:665
virtual void SetNoEdges(Bool_t noEdges=kTRUE)
if noEdges = kTRUE the lines connecting the center to the edges will not be drawn.
Definition TEllipse.cxx:656
void Copy(TObject &ellipse) const override
Copy this ellipse to ellipse.
Definition TEllipse.cxx:110
Double_t fPhimin
Minimum angle (degrees)
Definition TEllipse.h:30
Double_t GetY1() const
Definition TEllipse.h:50
TPoint GetBBoxCenter() override
Return the center of the Ellipse as TPoint in pixels.
Definition TEllipse.cxx:713
TEllipse()
Ellipse default constructor.
Definition TEllipse.cxx:57
Double_t fR1
first radius
Definition TEllipse.h:28
static TClass * Class()
@ kNoEdges
Definition TEllipse.h:37
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="")
Draw this ellipse with new coordinates.
Definition TEllipse.cxx:177
virtual void SetR2(Double_t r2)
Definition TEllipse.h:66
void Print(Option_t *option="") const override
Dump this ellipse with its attributes.
Definition TEllipse.cxx:612
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save primitive as a C++ statement(s) on output stream out.
Definition TEllipse.cxx:624
Mother of all ROOT objects.
Definition TObject.h:41
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:439
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:201
virtual void Streamer(TBuffer &)
Stream an object of class TObject.
Definition TObject.cxx:888
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:780
virtual void Copy(TObject &object) const
Copy this to obj.
Definition TObject.cxx:140
void ResetBit(UInt_t f)
Definition TObject.h:200
@ kCanDelete
if object in a list can be deleted
Definition TObject.h:62
static void IndentLevel()
Functions used by ls() to indent an object hierarchy.
Definition TROOT.cxx:2844
Basic string class.
Definition TString.h:139
void ToLower()
Change string to lower-case.
Definition TString.cxx:1182
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:632
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:250
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:646
constexpr Double_t DegToRad()
Conversion from degree to radian: .
Definition TMath.h:79
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:662
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:594
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:588
constexpr Double_t RadToDeg()
Conversion from radian to degree: .
Definition TMath.h:72
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:123
Rectangle structure (maps to the X11 XRectangle structure)
Definition GuiTypes.h:361
Short_t fX
Definition GuiTypes.h:362