Logo ROOT  
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 }
n
const Int_t n
Definition: legend1.C:16
kLeftSide
@ kLeftSide
Definition: GuiTypes.h:372
kTRUE
const Bool_t kTRUE
Definition: RtypesCore.h:91
TObject::TestBit
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
Version_t
short Version_t
Definition: RtypesCore.h:65
kTopSide
@ kTopSide
Definition: GuiTypes.h:372
TEllipse::SetBBoxY1
virtual void SetBBoxY1(const Int_t y)
Set top of BoundingBox to a value (resize in y direction on top)
Definition: TEllipse.cxx:738
kRightSide
@ kRightSide
Definition: GuiTypes.h:372
TMath::Max
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:212
TEllipse::SetNoEdges
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
TAttFill::Modify
virtual void Modify()
Change current fill area attributes if necessary.
Definition: TAttFill.cxx:211
kButton1Motion
@ kButton1Motion
Definition: Buttons.h:26
TPoint::GetX
SCoord_t GetX() const
Definition: TPoint.h:52
TMath::Cos
Double_t Cos(Double_t)
Definition: TMath.h:643
gVirtualX
#define gVirtualX
Definition: TVirtualX.h:338
Rectangle_t
Definition: GuiTypes.h:360
ClassImp
#define ClassImp(name)
Definition: Rtypes.h:364
TPoint::GetY
SCoord_t GetY() const
Definition: TPoint.h:53
TBuffer::ReadClassBuffer
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
TEllipse::GetBBoxCenter
virtual TPoint GetBBoxCenter()
Return the center of the Ellipse as TPoint in pixels.
Definition: TEllipse.cxx:676
kButton1Up
@ kButton1Up
Definition: Buttons.h:25
TMath::Sqrt
Double_t Sqrt(Double_t x)
Definition: TMath.h:691
TEllipse::SetBBoxY2
virtual void SetBBoxY2(const Int_t y)
Set bottom of BoundingBox to a value (resize in y direction on bottom)
Definition: TEllipse.cxx:751
Float_t
float Float_t
Definition: RtypesCore.h:57
TEllipse
Definition: TEllipse.h:23
Int_t
int Int_t
Definition: RtypesCore.h:45
TObject::AppendPad
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition: TObject.cxx:107
TEllipse::TEllipse
TEllipse()
Ellipse default constructor.
Definition: TEllipse.cxx:57
TString::Contains
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:624
TAttLine::SaveLineAttributes
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
TEllipse::fR2
Double_t fR2
second radius
Definition: TEllipse.h:29
x
Double_t x[n]
Definition: legend1.C:17
TVirtualX.h
TEllipse::SetBBoxCenter
virtual void SetBBoxCenter(const TPoint &p)
Set center of the Ellipse.
Definition: TEllipse.cxx:687
TMath::Abs
Short_t Abs(Short_t d)
Definition: TMathBase.h:120
TBuffer
Definition: TBuffer.h:43
TEllipse::~TEllipse
virtual ~TEllipse()
Ellipse default destructor.
Definition: TEllipse.cxx:87
kBottomSide
@ kBottomSide
Definition: GuiTypes.h:372
kMove
@ kMove
Definition: GuiTypes.h:373
kMouseMotion
@ kMouseMotion
Definition: Buttons.h:29
TEllipse::SetX1
virtual void SetX1(Double_t x1)
Definition: TEllipse.h:67
TBuffer::CheckByteCount
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
TString
Definition: TString.h:136
TAttFill::SaveFillAttributes
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
TEllipse::DistancetoPrimitive
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute distance from point px,py to an ellipse.
Definition: TEllipse.cxx:133
TEllipse::SetR2
virtual void SetR2(Double_t r2)
Definition: TEllipse.h:65
Rectangle_t::fY
Short_t fY
Definition: GuiTypes.h:361
bool
x1
static const double x1[5]
Definition: RooGaussKronrodIntegrator1D.cxx:346
TEllipse::GetY1
Double_t GetY1() const
Definition: TEllipse.h:49
TAttBBox2D
Definition: TAttBBox2D.h:19
TROOT.h
TEllipse::Draw
virtual void Draw(Option_t *option="")
Draw this ellipse with its current attributes.
Definition: TEllipse.cxx:168
TEllipse::DrawEllipse
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
TAttLine::Modify
virtual void Modify()
Change current line attributes if necessary.
Definition: TAttLine.cxx:242
Rectangle_t::fX
Short_t fX
Definition: GuiTypes.h:361
TObject::GetName
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:359
TEllipse::GetBBox
virtual Rectangle_t GetBBox()
Return the bounding Box of the Ellipse, currently not taking into account the rotating angle.
Definition: TEllipse.cxx:663
ROOT::Math::gv_detail::dist
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:63
TAttLine::Copy
void Copy(TAttLine &attline) const
Copy this line attributes to a new TAttLine.
Definition: TAttLine.cxx:172
TEllipse::fTheta
Double_t fTheta
Rotation angle (degrees)
Definition: TEllipse.h:32
Option_t
const typedef char Option_t
Definition: RtypesCore.h:66
TEllipse::kNoEdges
@ kNoEdges
Definition: TEllipse.h:37
TAttFill::Copy
void Copy(TAttFill &attfill) const
Copy this fill attributes to a new TAttFill.
Definition: TAttFill.cxx:202
TBuffer.h
TEllipse::fY1
Double_t fY1
Y coordinate of centre.
Definition: TEllipse.h:27
TAttLine
Definition: TAttLine.h:18
TObject::ResetBit
void ResetBit(UInt_t f)
Definition: TObject.h:171
TObject::SetBit
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:696
TEllipse::SetBBoxCenterX
virtual void SetBBoxCenterX(const Int_t x)
Set X coordinate of the center of the Ellipse.
Definition: TEllipse.cxx:696
kPI
const Double_t kPI
Definition: TEllipse.cxx:24
TEllipse::fPhimax
Double_t fPhimax
Maximum angle (degrees)
Definition: TEllipse.h:31
TBuffer::WriteClassBuffer
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
kFALSE
const Bool_t kFALSE
Definition: RtypesCore.h:92
TEllipse::Copy
void Copy(TObject &ellipse) const
Copy this ellipse to ellipse.
Definition: TEllipse.cxx:110
TEllipse::Paint
virtual void Paint(Option_t *option="")
Paint this ellipse with its current attributes.
Definition: TEllipse.cxx:520
TEllipse::SetBBoxCenterY
virtual void SetBBoxCenterY(const Int_t y)
Set Y coordinate of the center of the Ellipse.
Definition: TEllipse.cxx:704
TEllipse::SavePrimitive
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save primitive as a C++ statement(s) on output stream out.
Definition: TEllipse.cxx:589
TMath::Sin
Double_t Sin(Double_t)
Definition: TMath.h:639
TVirtualPad.h
UInt_t
unsigned int UInt_t
Definition: RtypesCore.h:46
TEllipse::Print
virtual void Print(Option_t *option="") const
Dump this ellipse with its attributes.
Definition: TEllipse.cxx:577
y
Double_t y[n]
Definition: legend1.C:17
TEllipse::GetNoEdges
Bool_t GetNoEdges() const
Return kTRUE if kNoEdges bit is set, kFALSE otherwise.
Definition: TEllipse.cxx:611
TEllipse::fX1
Double_t fX1
X coordinate of centre.
Definition: TEllipse.h:26
TBuffer::ReadVersion
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
TObject::kCanDelete
@ kCanDelete
if object in a list can be deleted
Definition: TObject.h:58
TROOT::IndentLevel
static void IndentLevel()
Functions used by ls() to indent an object hierarchy.
Definition: TROOT.cxx:2800
TMath::Min
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:180
kArrowKeyPress
@ kArrowKeyPress
Definition: Buttons.h:27
TEllipse::ExecuteEvent
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Execute action corresponding to one event.
Definition: TEllipse.cxx:199
TBuffer::IsReading
Bool_t IsReading() const
Definition: TBuffer.h:86
TEllipse::fPhimin
Double_t fPhimin
Minimum angle (degrees)
Definition: TEllipse.h:30
TEllipse::fR1
Double_t fR1
first radius
Definition: TEllipse.h:28
TEllipse::PaintEllipse
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
kButton1Down
@ kButton1Down
Definition: Buttons.h:23
TPoint
Definition: TPoint.h:31
Double_t
double Double_t
Definition: RtypesCore.h:59
TEllipse::ls
virtual void ls(Option_t *option="") const
List this ellipse with its attributes.
Definition: TEllipse.cxx:511
TEllipse::GetTheta
Double_t GetTheta() const
Definition: TEllipse.h:54
Rectangle_t::fHeight
UShort_t fHeight
Definition: GuiTypes.h:362
Rectangle_t::fWidth
UShort_t fWidth
Definition: GuiTypes.h:362
TObject
Definition: TObject.h:37
TPoint::SetY
void SetY(SCoord_t y)
Definition: TPoint.h:55
TEllipse::GetX1
Double_t GetX1() const
Definition: TEllipse.h:48
TEllipse.h
x2
static const double x2[5]
Definition: RooGaussKronrodIntegrator1D.cxx:364
gPad
#define gPad
Definition: TVirtualPad.h:287
TObject::Copy
virtual void Copy(TObject &object) const
Copy this to obj.
Definition: TObject.cxx:63
TEllipse::SetBBoxX2
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
TAttFill
Definition: TAttFill.h:19
TPoint.h
Class
void Class()
Definition: Class.C:29
TString::ToLower
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1125
TEllipse::SetBBoxX1
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
kArrowKeyRelease
@ kArrowKeyRelease
Definition: Buttons.h:27
TPoint::SetX
void SetX(SCoord_t x)
Definition: TPoint.h:54
TMath.h
TEllipse::SetR1
virtual void SetR1(Double_t r1)
Definition: TEllipse.h:64
TEllipse::SetY1
virtual void SetY1(Double_t y1)
Definition: TEllipse.h:68
gROOT
#define gROOT
Definition: TROOT.h:406
int