Logo ROOT   master
Reference Guide
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 <stdlib.h>
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 
24 const Double_t kPI = 3.14159265358979323846;
25 
27 
28 /** \class TEllipse
29 \ingroup BasicGraphics
30 
31 Draw Ellipses.
32 
33 The ellipse can be truncated and rotated. It is defined by its center `(x1,y1)`
34 and two radius `r1` and `r2`.
35 
36 A minimum and maximum angle may be specified `(phimin, phimax)`.
37 The ellipse may be rotated with an angle `theta`. All these
38 angles are in degrees.
39 The attributes of the outline line are given via `TAttLine`.
40 The attributes of the fill area are given via `TAttFill`.
41 The picture below illustrates different types of ellipses.
42 
43 When an ellipse sector only is drawn, the lines connecting the center
44 of the ellipse to the edges are drawn by default. One can specify
45 the drawing option "only" to not draw these lines or alternatively
46 call the function `SetNoEdges()`. To remove completely the ellipse
47 outline it is enough to specify 0 as line style.
48 
49 Begin_Macro(source)
50 ../../../tutorials/graphics/ellipse.C
51 End_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 
94 TEllipse::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  ((TEllipse&)ellipse).Copy(*this);
105 }
106 
107 ////////////////////////////////////////////////////////////////////////////////
108 /// Copy this ellipse to ellipse.
109 
110 void 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  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 
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 }
185 
186 ////////////////////////////////////////////////////////////////////////////////
187 /// Execute action corresponding to one event.
188 ///
189 /// This member function is called when a line is clicked with the locator
190 ///
191 /// If Left button clicked on one of the line end points, this point
192 /// follows the cursor until button is released.
193 ///
194 /// if Middle button clicked, the line is moved parallel to itself
195 /// until the button is released.
196 ///
197 /// NOTE that support for log scale is not implemented
198 
200 {
201  if (!gPad) return;
202 
203  Int_t kMaxDiff = 10;
204 
205  Int_t i, dpx, dpy;
206  Double_t angle,dx,dy,dphi,ct,st,fTy,fBy,fLx,fRx;
207  static Int_t px1,py1,npe,r1,r2,sav1,sav2;
208  const Int_t kMinSize = 25;
209  const Int_t np = 40;
210  static Bool_t pTop, pL, pR, pBot, pINSIDE;
211  static Int_t pTx,pTy,pLx,pLy,pRx,pRy,pBx,pBy;
212  static Int_t x[np+2], y[np+2];
213  static Int_t pxold, pyold;
214  static Int_t sig,impair;
215  static Double_t sdx, sdy;
216  static Double_t oldX1, oldY1, oldR1, oldR2;
217 
218  Bool_t opaque = gPad->OpaqueMoving();
219 
220  if (!gPad->IsEditable()) return;
221 
222  switch (event) {
223 
224  case kArrowKeyPress:
225  case kButton1Down:
226  oldX1 = fX1;
227  oldY1 = fY1;
228  oldR1 = fR1;
229  oldR2 = fR2;
230  dphi = (fPhimax-fPhimin)*kPI/(180*np);
231  ct = TMath::Cos(kPI*fTheta/180);
232  st = TMath::Sin(kPI*fTheta/180);
233  for (i=0;i<np;i++) {
234  angle = fPhimin*kPI/180 + Double_t(i)*dphi;
235  dx = fR1*TMath::Cos(angle);
236  dy = fR2*TMath::Sin(angle);
237  x[i] = gPad->XtoAbsPixel(fX1 + dx*ct - dy*st);
238  y[i] = gPad->YtoAbsPixel(fY1 + dx*st + dy*ct);
239  }
240  if (fPhimax-fPhimin >= 360 ) {
241  x[np] = x[0];
242  y[np] = y[0];
243  npe = np;
244  } else {
245  x[np] = gPad->XtoAbsPixel(fX1);
246  y[np] = gPad->YtoAbsPixel(fY1);
247  x[np+1] = x[0];
248  y[np+1] = y[0];
249  npe = np + 1;
250  }
251  impair = 0;
252  px1 = gPad->XtoAbsPixel(fX1);
253  py1 = gPad->YtoAbsPixel(fY1);
254  pTx = pBx = px1;
255  pLy = pRy = py1;
256  pTy = gPad->YtoAbsPixel(fR2+fY1);
257  pBy = gPad->YtoAbsPixel(-fR2+fY1);
258  pLx = gPad->XtoAbsPixel(-fR1+fX1);
259  pRx = gPad->XtoAbsPixel(fR1+fX1);
260  r2 = (pBy-pTy)/2;
261  r1 = (pRx-pLx)/2;
262  if (!opaque) {
263  gVirtualX->SetLineColor(-1);
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(pRx-4, py1-4, pRx+4, py1-4);
268  gVirtualX->DrawLine(pRx+4, py1-4, pRx+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(pLx-4, py1-4, pLx+4, py1-4);
272  gVirtualX->DrawLine(pLx+4, py1-4, pLx+4, py1+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, pBy-4, px1+4, pBy-4);
276  gVirtualX->DrawLine(px1+4, pBy-4, px1+4, pBy+4);
277  gVirtualX->DrawLine(px1+4, pTy+4, px1-4, pTy+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  }
282  else {
283  sdx = this->GetX1()-gPad->AbsPixeltoX(px);
284  sdy = this->GetY1()-gPad->AbsPixeltoY(py);
285  }
286  // No break !!!
287 
288  case kMouseMotion:
289  px1 = gPad->XtoAbsPixel(fX1);
290  py1 = gPad->YtoAbsPixel(fY1);
291  pTx = pBx = px1;
292  pLy = pRy = py1;
293  pTy = gPad->YtoAbsPixel(fR2+fY1);
294  pBy = gPad->YtoAbsPixel(-fR2+fY1);
295  pLx = gPad->XtoAbsPixel(-fR1+fX1);
296  pRx = gPad->XtoAbsPixel(fR1+fX1);
297  pTop = pL = pR = pBot = pINSIDE = kFALSE;
298  if ((TMath::Abs(px - pTx) < kMaxDiff) &&
299  (TMath::Abs(py - pTy) < kMaxDiff)) { // top edge
300  pTop = kTRUE;
301  gPad->SetCursor(kTopSide);
302  }
303  else
304  if ((TMath::Abs(px - pBx) < kMaxDiff) &&
305  (TMath::Abs(py - pBy) < kMaxDiff)) { // bottom edge
306  pBot = kTRUE;
307  gPad->SetCursor(kBottomSide);
308  }
309  else
310  if ((TMath::Abs(py - pLy) < kMaxDiff) &&
311  (TMath::Abs(px - pLx) < kMaxDiff)) { // left edge
312  pL = kTRUE;
313  gPad->SetCursor(kLeftSide);
314  }
315  else
316  if ((TMath::Abs(py - pRy) < kMaxDiff) &&
317  (TMath::Abs(px - pRx) < kMaxDiff)) { // right edge
318  pR = kTRUE;
319  gPad->SetCursor(kRightSide);
320  }
321  else {pINSIDE= kTRUE; gPad->SetCursor(kMove); }
322  pxold = px; pyold = py;
323 
324  break;
325 
326  case kArrowKeyRelease:
327  case kButton1Motion:
328  if (!opaque)
329  {
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(pRx-4, py1-4, pRx+4, py1-4);
333  gVirtualX->DrawLine(pRx+4, py1-4, pRx+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(pLx-4, py1-4, pLx+4, py1-4);
337  gVirtualX->DrawLine(pLx+4, py1-4, pLx+4, py1+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, pBy-4, px1+4, pBy-4);
341  gVirtualX->DrawLine(px1+4, pBy-4, px1+4, pBy+4);
342  gVirtualX->DrawLine(px1+4, pTy+4, px1-4, pTy+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  for (i=0;i<npe;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
347  }
348  if (pTop) {
349  sav1 = py1;
350  sav2 = r2;
351  py1 += (py - pyold)/2;
352  r2 -= (py - pyold)/2;
353  if (TMath::Abs(pyold-py)%2==1) impair++;
354  if (py-pyold>0) sig=+1;
355  else sig=-1;
356  if (impair==2) { impair = 0; py1 += sig; r2 -= sig;}
357  if (py1 > pBy-kMinSize) {py1 = sav1; r2 = sav2; py = pyold;}
358  }
359  if (pBot) {
360  sav1 = py1;
361  sav2 = r2;
362  py1 += (py - pyold)/2;
363  r2 += (py - pyold)/2;
364  if (TMath::Abs(pyold-py)%2==1) impair++;
365  if (py-pyold>0) sig=+1;
366  else sig=-1;
367  if (impair==2) { impair = 0; py1 += sig; r2 += sig;}
368  if (py1 < pTy+kMinSize) {py1 = sav1; r2 = sav2; py = pyold;}
369  }
370  if (pL) {
371  sav1 = px1;
372  sav2 = r1;
373  px1 += (px - pxold)/2;
374  r1 -= (px - pxold)/2;
375  if (TMath::Abs(pxold-px)%2==1) impair++;
376  if (px-pxold>0) sig=+1;
377  else sig=-1;
378  if (impair==2) { impair = 0; px1 += sig; r1 -= sig;}
379  if (px1 > pRx-kMinSize) {px1 = sav1; r1 = sav2; px = pxold;}
380  }
381  if (pR) {
382  sav1 = px1;
383  sav2 = r1;
384  px1 += (px - pxold)/2;
385  r1 += (px - pxold)/2;
386  if (TMath::Abs(pxold-px)%2==1) impair++;
387  if (px-pxold>0) sig=+1;
388  else sig=-1;
389  if (impair==2) { impair = 0; px1 += sig; r1 += sig;}
390  if (px1 < pLx+kMinSize) {px1 = sav1; r1 = sav2; px = pxold;}
391  }
392  if (pTop || pBot || pL || pR) {
393  if (!opaque) {
394  dphi = (fPhimax-fPhimin)*kPI/(180*np);
395  ct = TMath::Cos(kPI*fTheta/180);
396  st = TMath::Sin(kPI*fTheta/180);
397  for (i=0;i<np;i++) {
398  angle = fPhimin*kPI/180 + Double_t(i)*dphi;
399  dx = r1*TMath::Cos(angle);
400  dy = r2*TMath::Sin(angle);
401  x[i] = px1 + Int_t(dx*ct - dy*st);
402  y[i] = py1 + Int_t(dx*st + dy*ct);
403  }
404  if (fPhimax-fPhimin >= 360 ) {
405  x[np] = x[0];
406  y[np] = y[0];
407  npe = np;
408  } else {
409  x[np] = px1;
410  y[np] = py1;
411  x[np+1] = x[0];
412  y[np+1] = y[0];
413  npe = np + 1;
414  }
415  gVirtualX->SetLineColor(-1);
417  for (i=0;i<npe;i++)
418  gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
419  }
420  else
421  {
422  this->SetX1(gPad->AbsPixeltoX(px1));
423  this->SetY1(gPad->AbsPixeltoY(py1));
424  this->SetR1(TMath::Abs(gPad->AbsPixeltoX(px1-r1)-gPad->AbsPixeltoX(px1+r1))/2);
425  this->SetR2(TMath::Abs(gPad->AbsPixeltoY(py1-r2)-gPad->AbsPixeltoY(py1+r2))/2);
426  if (pTop) gPad->ShowGuidelines(this, event, 't', true);
427  if (pBot) gPad->ShowGuidelines(this, event, 'b', true);
428  if (pL) gPad->ShowGuidelines(this, event, 'l', true);
429  if (pR) gPad->ShowGuidelines(this, event, 'r', true);
430  gPad->Modified(kTRUE);
431  gPad->Update();
432  }
433  }
434  if (pINSIDE) {
435  if (!opaque){
436  dpx = px-pxold; dpy = py-pyold;
437  px1 += dpx; py1 += dpy;
438  for (i=0;i<=npe;i++) { x[i] += dpx; y[i] += dpy;}
439  for (i=0;i<npe;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
440  }
441  else {
442  this->SetX1(gPad->AbsPixeltoX(px)+sdx);
443  this->SetY1(gPad->AbsPixeltoY(py)+sdy);
444  gPad->ShowGuidelines(this, event, 'i', true);
445  gPad->Modified(kTRUE);
446  gPad->Update();
447  }
448  }
449  if (!opaque){
450  pTx = pBx = px1;
451  pRx = px1+r1;
452  pLx = px1-r1;
453  pRy = pLy = py1;
454  pTy = py1-r2;
455  pBy = py1+r2;
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(pRx-4, py1-4, pRx+4, py1-4);
459  gVirtualX->DrawLine(pRx+4, py1-4, pRx+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(pLx-4, py1-4, pLx+4, py1-4);
463  gVirtualX->DrawLine(pLx+4, py1-4, pLx+4, py1+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, pBy-4, px1+4, pBy-4);
467  gVirtualX->DrawLine(px1+4, pBy-4, px1+4, pBy+4);
468  gVirtualX->DrawLine(px1+4, pTy+4, px1-4, pTy+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  }
473  pxold = px;
474  pyold = py;
475  break;
476 
477  case kButton1Up:
478  if (gROOT->IsEscaped()) {
479  gROOT->SetEscape(kFALSE);
480  if (opaque) {
481  this->SetX1(oldX1);
482  this->SetY1(oldY1);
483  this->SetR1(oldR1);
484  this->SetR2(oldR2);
485  gPad->Modified(kTRUE);
486  gPad->Update();
487  }
488  break;
489  }
490 
491  if (opaque) {
492  gPad->ShowGuidelines(this, event);
493  } else {
494  fX1 = gPad->AbsPixeltoX(px1);
495  fY1 = gPad->AbsPixeltoY(py1);
496  fBy = gPad->AbsPixeltoY(py1+r2);
497  fTy = gPad->AbsPixeltoY(py1-r2);
498  fLx = gPad->AbsPixeltoX(px1+r1);
499  fRx = gPad->AbsPixeltoX(px1-r1);
500  fR1 = TMath::Abs(fRx-fLx)/2;
501  fR2 = TMath::Abs(fTy-fBy)/2;
502  gPad->Modified(kTRUE);
503  gVirtualX->SetLineColor(-1);
504  }
505  }
506 }
507 
508 ////////////////////////////////////////////////////////////////////////////////
509 /// List this ellipse with its attributes.
510 
511 void TEllipse::ls(Option_t *) const
512 {
514  printf("%s: X1= %f Y1=%f R1=%f R2=%f\n",GetName(),fX1,fY1,fR1,fR2);
515 }
516 
517 ////////////////////////////////////////////////////////////////////////////////
518 /// Paint this ellipse with its current attributes.
519 
521 {
523 }
524 
525 ////////////////////////////////////////////////////////////////////////////////
526 /// Draw this ellipse with new coordinates.
527 
529  Double_t phimin, Double_t phimax, Double_t theta,
530  Option_t *option)
531 {
532  const Int_t np = 200;
533  static Double_t x[np+3], y[np+3];
534  TAttLine::Modify(); //Change line attributes only if necessary
535  TAttFill::Modify(); //Change fill attributes only if necessary
536 
537  Double_t phi1 = TMath::Min(phimin,phimax);
538  Double_t phi2 = TMath::Max(phimin,phimax);
539 
540  //set number of points approximatively proportional to the ellipse circumference
541  Double_t circ = kPI*(r1+r2)*(phi2-phi1)/360;
542  Int_t n = (Int_t)(np*circ/((gPad->GetX2()-gPad->GetX1())+(gPad->GetY2()-gPad->GetY1())));
543  if (n < 8) n= 8;
544  if (n > np) n = np;
545  Double_t angle,dx,dy;
546  Double_t dphi = (phi2-phi1)*kPI/(180*n);
547  Double_t ct = TMath::Cos(kPI*theta/180);
548  Double_t st = TMath::Sin(kPI*theta/180);
549  for (Int_t i=0;i<=n;i++) {
550  angle = phi1*kPI/180 + Double_t(i)*dphi;
551  dx = r1*TMath::Cos(angle);
552  dy = r2*TMath::Sin(angle);
553  x[i] = gPad->XtoPad(x1 + dx*ct - dy*st);
554  y[i] = gPad->YtoPad(y1 + dx*st + dy*ct);
555  }
556  TString opt = option;
557  opt.ToLower();
558  if (phi2-phi1 >= 360 ) {
559  if (GetFillStyle()) gPad->PaintFillArea(n,x,y);
560  if (GetLineStyle()) gPad->PaintPolyLine(n+1,x,y);
561  } else {
562  x[n+1] = gPad->XtoPad(x1);
563  y[n+1] = gPad->YtoPad(y1);
564  x[n+2] = x[0];
565  y[n+2] = y[0];
566  if (GetFillStyle()) gPad->PaintFillArea(n+2,x,y);
567  if (GetLineStyle()) {
568  if (TestBit(kNoEdges) || opt.Contains("only")) gPad->PaintPolyLine(n+1,x,y);
569  else gPad->PaintPolyLine(n+3,x,y);
570  }
571  }
572 }
573 
574 ////////////////////////////////////////////////////////////////////////////////
575 /// Dump this ellipse with its attributes.
576 
578 {
579  printf("Ellipse: X1=%f Y1=%f R1=%f R2=%f",fX1,fY1,fR1,fR2);
580  if (GetLineColor() != 1) printf(" Color=%d",GetLineColor());
581  if (GetLineStyle() != 1) printf(" Style=%d",GetLineStyle());
582  if (GetLineWidth() != 1) printf(" Width=%d",GetLineWidth());
583  printf("\n");
584 }
585 
586 ////////////////////////////////////////////////////////////////////////////////
587 /// Save primitive as a C++ statement(s) on output stream out
588 
589 void TEllipse::SavePrimitive(std::ostream &out, Option_t * /*= ""*/)
590 {
591  out<<" "<<std::endl;
592  if (gROOT->ClassSaved(TEllipse::Class())) {
593  out<<" ";
594  } else {
595  out<<" TEllipse *";
596  }
597  out<<"ellipse = new TEllipse("<<fX1<<","<<fY1<<","<<fR1<<","<<fR2
598  <<","<<fPhimin<<","<<fPhimax<<","<<fTheta<<");"<<std::endl;
599 
600  SaveFillAttributes(out,"ellipse",0,1001);
601  SaveLineAttributes(out,"ellipse",1,1,1);
602 
603  if (GetNoEdges()) out<<" ellipse->SetNoEdges();"<<std::endl;
604 
605  out<<" ellipse->Draw();"<<std::endl;
606 }
607 
608 ////////////////////////////////////////////////////////////////////////////////
609 /// Return kTRUE if kNoEdges bit is set, kFALSE otherwise.
610 
612 {
613  return TestBit(kNoEdges) ? kTRUE : kFALSE;
614 }
615 
616 ////////////////////////////////////////////////////////////////////////////////
617 /// if noEdges = kTRUE the lines connecting the center to the edges
618 /// will not be drawn.
619 /// default is to draw the edges.
620 
622 {
623  if (noEdges) SetBit(kNoEdges);
624  else ResetBit(kNoEdges);
625 }
626 
627 ////////////////////////////////////////////////////////////////////////////////
628 /// Stream an object of class TEllipse.
629 
630 void TEllipse::Streamer(TBuffer &R__b)
631 {
632  if (R__b.IsReading()) {
633  UInt_t R__s, R__c;
634  Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
635  if (R__v > 1) {
636  R__b.ReadClassBuffer(TEllipse::Class(), this, R__v, R__s, R__c);
637  return;
638  }
639  //====process old versions before automatic schema evolution
640  TObject::Streamer(R__b);
641  TAttLine::Streamer(R__b);
642  TAttFill::Streamer(R__b);
643  Float_t x1,y1,r1,r2,phimin,phimax,theta;
644  R__b >> x1; fX1 = x1;
645  R__b >> y1; fY1 = y1;
646  R__b >> r1; fR1 = r1;
647  R__b >> r2; fR2 = r2;
648  R__b >> phimin; fPhimin = phimin;
649  R__b >> phimax; fPhimax = phimax;
650  R__b >> theta; fTheta = theta;
651  R__b.CheckByteCount(R__s, R__c, TEllipse::IsA());
652  //====end of old versions
653 
654  } else {
655  R__b.WriteClassBuffer(TEllipse::Class(),this);
656  }
657 }
658 
659 ////////////////////////////////////////////////////////////////////////////////
660 /// Return the bounding Box of the Ellipse, currently not taking into
661 /// account the rotating angle.
662 
664 {
665  Rectangle_t BBox;
666  BBox.fX = gPad->XtoPixel(fX1-fR1);
667  BBox.fY = gPad->YtoPixel(fY1+fR2);
668  BBox.fWidth = gPad->XtoPixel(fX1+fR1)-gPad->XtoPixel(fX1-fR1);
669  BBox.fHeight = gPad->YtoPixel(fY1-fR2)-gPad->YtoPixel(fY1+fR2);
670  return (BBox);
671 }
672 
673 ////////////////////////////////////////////////////////////////////////////////
674 /// Return the center of the Ellipse as TPoint in pixels
675 
677 {
678  TPoint p;
679  p.SetX(gPad->XtoPixel(fX1));
680  p.SetY(gPad->YtoPixel(fY1));
681  return(p);
682 }
683 
684 ////////////////////////////////////////////////////////////////////////////////
685 /// Set center of the Ellipse
686 
688 {
689  fX1 = gPad->PixeltoX(p.GetX());
690  fY1 = gPad->PixeltoY(p.GetY()-gPad->VtoPixel(0));
691 }
692 
693 ////////////////////////////////////////////////////////////////////////////////
694 /// Set X coordinate of the center of the Ellipse
695 
697 {
698  fX1 = gPad->PixeltoX(x);
699 }
700 
701 ////////////////////////////////////////////////////////////////////////////////
702 /// Set Y coordinate of the center of the Ellipse
703 
705 {
706  fY1 = gPad->PixeltoY(y-gPad->VtoPixel(0));
707 }
708 
709 ////////////////////////////////////////////////////////////////////////////////
710 /// Set left hand side of BoundingBox to a value
711 /// (resize in x direction on left)
712 
714 {
715  Double_t x1 = gPad->PixeltoX(x);
716  if (x1>fX1+fR1) return;
717 
718  fR1 = (fX1+fR1-x1)*0.5;
719  fX1 = x1 + fR1;
720 }
721 
722 ////////////////////////////////////////////////////////////////////////////////
723 /// Set right hand side of BoundingBox to a value
724 /// (resize in x direction on right)
725 
727 {
728  Double_t x2 = gPad->PixeltoX(x);
729  if (x2<fX1-fR1) return;
730 
731  fR1 = (x2-fX1+fR1)*0.5;
732  fX1 = x2-fR1;
733 }
734 
735 ////////////////////////////////////////////////////////////////////////////////
736 /// Set top of BoundingBox to a value (resize in y direction on top)
737 
739 {
740  Double_t y1 = gPad->PixeltoY(y-gPad->VtoPixel(0));
741  if (y1<fY1-fR2) return;
742 
743  fR2 = (y1-fY1+fR2)*0.5;
744  fY1 = y1-fR2;
745 }
746 
747 ////////////////////////////////////////////////////////////////////////////////
748 /// Set bottom of BoundingBox to a value
749 /// (resize in y direction on bottom)
750 
752 {
753  Double_t y2 = gPad->PixeltoY(y-gPad->VtoPixel(0));
754 
755  if (y2>fY1+fR2) return;
756 
757  fR2 = (fY1+fR2-y2)*0.5;
758  fY1 = y2+fR2;
759 }
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Execute action corresponding to one event.
Definition: TEllipse.cxx:199
UShort_t fWidth
Definition: GuiTypes.h:362
Bool_t IsReading() const
Definition: TBuffer.h:85
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
void SetX(SCoord_t x)
Definition: TPoint.h:48
Short_t fY
Definition: GuiTypes.h:361
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
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:528
virtual void 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:176
Double_t GetTheta() const
Definition: TEllipse.h:54
UShort_t fHeight
Definition: GuiTypes.h:362
Double_t fX1
X coordinate of centre.
Definition: TEllipse.h:26
short Version_t
Definition: RtypesCore.h:63
float Float_t
Definition: RtypesCore.h:55
unsigned int UInt_t
Definition: CPyCppyy.h:44
const char Option_t
Definition: RtypesCore.h:64
Double_t fY1
Y coordinate of centre.
Definition: TEllipse.h:27
virtual void ls(Option_t *option="") const
List this ellipse with its attributes.
Definition: TEllipse.cxx:511
virtual void SetBBoxCenterX(const Int_t x)
Set X coordinate of the center of the Ellipse.
Definition: TEllipse.cxx:696
int Int_t
Definition: CPyCppyy.h:43
Double_t GetY1() const
Definition: TEllipse.h:49
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save primitive as a C++ statement(s) on output stream out.
Definition: TEllipse.cxx:589
Buffer base class used for serializing objects.
Definition: TBuffer.h:42
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
#define gROOT
Definition: TROOT.h:405
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
TEllipse()
Ellipse default constructor.
Definition: TEllipse.cxx:57
Basic string class.
Definition: TString.h:131
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:180
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1125
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute distance from point px,py to an ellipse.
Definition: TEllipse.cxx:133
SCoord_t GetY() const
Definition: TPoint.h:47
SCoord_t GetX() const
Definition: TPoint.h:46
virtual void SetBBoxX1(const Int_t x)
Set left hand side of BoundingBox to a value (resize in x direction on left)
Definition: TEllipse.cxx:713
virtual void Modify()
Change current line attributes if necessary.
Definition: TAttLine.cxx:242
virtual void SetR1(Double_t r1)
Definition: TEllipse.h:64
void SetY(SCoord_t y)
Definition: TPoint.h:49
Short_t Abs(Short_t d)
Definition: TMathBase.h:120
virtual Width_t GetLineWidth() const
Return the line width.
Definition: TAttLine.h:35
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:695
if object in a list can be deleted
Definition: TObject.h:58
virtual void Paint(Option_t *option="")
Paint this ellipse with its current attributes.
Definition: TEllipse.cxx:520
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition: TObject.cxx:106
virtual Style_t GetLineStyle() const
Return the line style.
Definition: TAttLine.h:34
static const double x2[5]
Fill Area Attributes class.
Definition: TAttFill.h:19
Double_t x[n]
Definition: legend1.C:17
void Class()
Definition: Class.C:29
void Copy(TAttLine &attline) const
Copy this line attributes to a new TAttLine.
Definition: TAttLine.cxx:172
virtual void Copy(TObject &object) const
Copy this to obj.
Definition: TObject.cxx:62
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:270
virtual void Modify()
Change current fill area attributes if necessary.
Definition: TAttFill.cxx:211
virtual void SetBBoxY1(const Int_t y)
Set top of BoundingBox to a value (resize in y direction on top)
Definition: TEllipse.cxx:738
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:621
Short_t fX
Definition: GuiTypes.h:361
virtual void Draw(Option_t *option="")
Draw this ellipse with its current attributes.
Definition: TEllipse.cxx:168
Definition: TPoint.h:31
Double_t fTheta
Rotation angle (degrees)
Definition: TEllipse.h:32
Double_t fR1
first radius
Definition: TEllipse.h:28
Double_t fPhimax
Maximum angle (degrees)
Definition: TEllipse.h:31
virtual void SetY1(Double_t y1)
Definition: TEllipse.h:68
virtual void SetBBoxX2(const Int_t x)
Set right hand side of BoundingBox to a value (resize in x direction on right)
Definition: TEllipse.cxx:726
virtual void SetBBoxCenterY(const Int_t y)
Set Y coordinate of the center of the Ellipse.
Definition: TEllipse.cxx:704
virtual void Print(Option_t *option="") const
Dump this ellipse with its attributes.
Definition: TEllipse.cxx:577
virtual void SetX1(Double_t x1)
Definition: TEllipse.h:67
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:234
virtual void SetR2(Double_t r2)
Definition: TEllipse.h:65
static void IndentLevel()
Functions used by ls() to indent an object hierarchy.
Definition: TROOT.cxx:2791
const Double_t kPI
Definition: TEllipse.cxx:24
Double_t fR2
second radius
Definition: TEllipse.h:29
#define gVirtualX
Definition: TVirtualX.h:338
Double_t Cos(Double_t)
Definition: TMath.h:631
const Bool_t kFALSE
Definition: RtypesCore.h:90
virtual Color_t GetLineColor() const
Return the line color.
Definition: TAttLine.h:33
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
virtual ~TEllipse()
Ellipse default destructor.
Definition: TEllipse.cxx:87
static const double x1[5]
#define ClassImp(name)
Definition: Rtypes.h:361
double Double_t
Definition: RtypesCore.h:57
virtual TPoint GetBBoxCenter()
Return the center of the Ellipse as TPoint in pixels.
Definition: TEllipse.cxx:676
virtual void SetBBoxCenter(const TPoint &p)
Set center of the Ellipse.
Definition: TEllipse.cxx:687
Double_t y[n]
Definition: legend1.C:17
virtual Color_t GetFillColor() const
Return the fill area color.
Definition: TAttFill.h:30
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
Double_t GetX1() const
Definition: TEllipse.h:48
Draw Ellipses.
Definition: TEllipse.h:23
Mother of all ROOT objects.
Definition: TObject.h:37
void Copy(TObject &ellipse) const
Copy this ellipse to ellipse.
Definition: TEllipse.cxx:110
Abstract base class for elements drawn in the editor.
Definition: TAttBBox2D.h:19
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:212
virtual void SetBBoxY2(const Int_t y)
Set bottom of BoundingBox to a value (resize in y direction on bottom)
Definition: TEllipse.cxx:751
Double_t Sin(Double_t)
Definition: TMath.h:627
virtual Rectangle_t GetBBox()
Return the bounding Box of the Ellipse, currently not taking into account the rotating angle...
Definition: TEllipse.cxx:663
#define gPad
Definition: TVirtualPad.h:287
Bool_t GetNoEdges() const
Return kTRUE if kNoEdges bit is set, kFALSE otherwise.
Definition: TEllipse.cxx:611
void ResetBit(UInt_t f)
Definition: TObject.h:171
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition: TAttFill.h:31
Double_t Sqrt(Double_t x)
Definition: TMath.h:681
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:358
Double_t fPhimin
Minimum angle (degrees)
Definition: TEllipse.h:30
const Bool_t kTRUE
Definition: RtypesCore.h:89
const Int_t n
Definition: legend1.C:16
Line Attributes class.
Definition: TAttLine.h:18
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
void Copy(TAttFill &attfill) const
Copy this fill attributes to a new TAttFill.
Definition: TAttFill.cxx:202