ROOT   6.08/07 Reference Guide
TCurlyLine.cxx
Go to the documentation of this file.
1 // @(#)root/graf:$Id$
2 // Author: Otto Schaile 20/11/99
3
4 /*************************************************************************
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. * 9 * For the list of contributors see$ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11
12 /** \class TCurlyLine
13 \ingroup BasicGraphics
14
15 Implements curly or wavy polylines used to draw Feynman diagrams.
16
17 Amplitudes and wavelengths may be specified in the constructors,
18 via commands or interactively from popup menus.
19 The class make use of TPolyLine by inheritance, ExecuteEvent methods
20 are highly inspired from the methods used in TPolyLine and TArc.
21 The picture below has been generated by the tutorial feynman.
22
23 Begin_Macro(source)
24 ../../../tutorials/graphics/feynman.C
25 End_Macro
26 */
27
28 #include "Riostream.h"
29 #include "TCurlyLine.h"
30 #include "TROOT.h"
32 #include "TVirtualX.h"
33 #include "TMath.h"
34 #include "TLine.h"
35 #include "TPoint.h"
36
40
42
43 ////////////////////////////////////////////////////////////////////////////////
44 /// Default constructor.
45
47 {
48  fX1 = 0.;
49  fY1 = 0.;
50  fX2 = 0.;
51  fY2 = 0.;
52  fWaveLength = 0.;
53  fAmplitude = 0.;
55  fNsteps = 0;
56 }
57
58 ////////////////////////////////////////////////////////////////////////////////
59 /// Create a new TCurlyLine with starting point (x1, y1), end point (x2,y2).
60 /// The wavelength and amplitude are given in percent of the pad height.
61
63 {
64  fX1 = x1;
65  fY1 = y1;
66  fX2 = x2;
67  fY2 = y2;
68  fWaveLength = wl;
69  fAmplitude = amp;
71  Build();
72 }
73
74 ////////////////////////////////////////////////////////////////////////////////
75 /// Create a curly (Gluon) or wavy (Gamma) line.
76
77 void TCurlyLine::Build()
78 {
79  Double_t pixeltoX = 1;
80  Double_t pixeltoY = 1;
81
82  Double_t wavelengthPix,amplitudePix, lengthPix, hPix;
83  Double_t px1, py1, px2, py2;
88  Double_t pyrange = - gPad->GetAbsHNDC()*wh;
91  pixeltoX = xrange / pxrange;
92  pixeltoY = yrange/pyrange;
98
99  lengthPix = TMath::Sqrt((px2-px1)*(px2-px1) + (py1-py2)*(py1-py2));
100  wavelengthPix = hPix*fWaveLength;
101  amplitudePix = hPix*fAmplitude;
102  } else {
103  wavelengthPix = fWaveLength;
104  amplitudePix = fAmplitude;
105  px1 = fX1;
106  py1 = fY1;
107  px2 = fX2;
108  py2 = fY2;
109  lengthPix = TMath::Sqrt((px2-px1)*(px2-px1) + (py1-py2)*(py1-py2));
110  }
111  // construct the curly / wavy line in pixel coordinates at angle 0
112  Double_t anglestep = 40;
113  Double_t phimaxle = TMath::Pi() * 2. / anglestep ;
114  Double_t dx = wavelengthPix / 40;
115  Double_t len2pi = dx * anglestep;
116
117  // make sure there is a piece of straight line a both ends
118
119  Double_t lengthcycle = 0.5 * len2pi + 2 * amplitudePix;
120  // if (fIsCurly) lengthcycle += amplitudePix;
121  Int_t nperiods = (Int_t)((lengthPix - lengthcycle) / len2pi);
122  Double_t restlength = 0.5 * (lengthPix - nperiods * len2pi - lengthcycle);
123  fNsteps = (Int_t)(anglestep * nperiods + anglestep / 2 + 4);
124  if (fNsteps < 2) fNsteps = 2;
126  Double_t *xv = GetX();
127  Double_t *yv = GetY();
128  xv[0] = 0; yv[0] = 0;
129  xv[1] = restlength; yv[1] = 0;
130  Double_t phase = 1.5 * TMath::Pi();
131  Double_t x0 = amplitudePix + restlength;
132  Int_t i;
133  for(i = 2; i < fNsteps-1; i++){
134  // distinguish between curly and wavy
135  if (fIsCurly) xv[i] = x0 + amplitudePix * TMath::Sin(phase);
136  else xv[i] = x0;
137  yv[i] = amplitudePix*TMath::Cos(phase);
138  phase += phimaxle;
139  x0 += dx;
140  }
141  xv[fNsteps-1] = lengthPix; yv[fNsteps-1] = 0;
142
143  if (InheritsFrom("TCurlyArc")) return; // called by TCurlyArc
144
145  // rotate object and transform back to user coordinates
146  Double_t angle = TMath::ATan2(py2-py1, px2-px1);
147  if (angle < 0) angle += 2*TMath::Pi();
148
149  Double_t cosang = TMath::Cos(angle);
150  Double_t sinang = TMath::Sin(angle);
151  Double_t xx, yy;
152
153  for(i = 0; i < fNsteps; i++){
154  xx = xv[i] * cosang - yv[i] * sinang;
155  yy = xv[i] * sinang + yv[i] * cosang;
157  xx *= pixeltoX;
158  yy *= pixeltoY;
159  }
160  xv[i] = xx + fX1;
161  yv[i] = yy + fY1;
162  }
164 }
165
166 ////////////////////////////////////////////////////////////////////////////////
167 /// Compute distance from point px,py to a line.
168
170 {
171  return DistancetoLine(px,py,fX1,fY1,fX2,fY2);
172 }
173
174 ////////////////////////////////////////////////////////////////////////////////
175 /// Execute action corresponding to one event.
176 ///
177 /// This member function is called when a TCurlyLine is clicked with the locator
178 ///
179 /// If Left button clicked on one of the line end points, this point
180 /// follows the cursor until button is released.
181 ///
182 /// if Middle button clicked, the line is moved parallel to itself
183 /// until the button is released.
184
185 void TCurlyLine::ExecuteEvent(Int_t event, Int_t px, Int_t py)
186 {
188
189  Int_t kMaxDiff = 20;
190  static Int_t d1,d2,px1,px2,py1,py2;
191  static Int_t pxold, pyold, px1old, py1old, px2old, py2old;
192  static Bool_t p1, p2, pL;
193  Int_t dx, dy;
194
196
197  switch (event) {
198
199  case kArrowKeyPress:
200  case kButton1Down:
201  if (!opaque) {
202  gVirtualX->SetLineColor(-1);
203  TAttLine::Modify(); //Change line attributes only if necessary
204  }
205
206  // No break !!!
207
208  case kMouseMotion:
209
214
215  p1 = p2 = pL = kFALSE;
216
217  d1 = TMath::Abs(px1 - px) + TMath::Abs(py1-py); //simply take sum of pixels differences
218  if (d1 < kMaxDiff) { //*-*================>OK take point number 1
219  px1old = px1; py1old = py1;
220  p1 = kTRUE;
222  return;
223  }
224  d2 = TMath::Abs(px2 - px) + TMath::Abs(py2-py); //simply take sum of pixels differences
225  if (d2 < kMaxDiff) { //*-*================>OK take point number 2
226  px2old = px2; py2old = py2;
227  p2 = kTRUE;
229  return;
230  }
231
232  pL = kTRUE;
233  pxold = px; pyold = py;
235
236  break;
237
238  case kArrowKeyRelease:
239  case kButton1Motion:
240
241  if (p1) {
242  if (!opaque) {
243  gVirtualX->DrawLine(px1old, py1old, px2, py2);
244  gVirtualX->DrawLine(px, py, px2, py2);
245  }
247  px1old = px;
248  py1old = py;
249  }
250  if (p2) {
251  if (!opaque) {
252  gVirtualX->DrawLine(px1, py1, px2old, py2old);
253  gVirtualX->DrawLine(px1, py1, px, py);
254  }
256  px2old = px;
257  py2old = py;
258  }
259  if (pL) {
260  if (!opaque) gVirtualX->DrawLine(px1, py1, px2, py2);
261  dx = px-pxold; dy = py-pyold;
262  px1 += dx; py1 += dy; px2 += dx; py2 += dy;
263  if (!opaque) gVirtualX->DrawLine(px1, py1, px2, py2);
264  pxold = px;
265  pyold = py;
266  if (opaque) {
269  }
270  }
271
272  if (opaque) {
273  if (p1) {
274  //check in which corner the BBox is edited
275  if (fX1>fX2) {
276  if (fY1>fY2)
278  else
280  }
281  else {
282  if (fY1>fY2)
284  else
286  }
287  }
288  if (p2) {
289  //check in which corner the BBox is edited
290  if (fX1>fX2) {
291  if (fY1>fY2)
293  else
295  }
296  else {
297  if (fY1>fY2)
299  else
301  }
302  }
303  if (pL) {
305  }
308  }
309  break;
310
311  case kButton1Up:
312
313  if (opaque) {
315  } else {
316  if (p1) {
319  }
320  if (p2) {
323  }
324  if (pL) {
329  }
330  }
331  Build();
333  if (!opaque) gVirtualX->SetLineColor(-1);
334  }
335 }
336
337 ////////////////////////////////////////////////////////////////////////////////
338 /// Save primitive as a C++ statement(s) on output stream out
339
340 void TCurlyLine::SavePrimitive(std::ostream &out, Option_t * /*= ""*/)
341 {
342  if (gROOT->ClassSaved(TCurlyLine::Class())) {
343  out<<" ";
344  } else {
345  out<<" TCurlyLine *";
346  }
347  out<<"curlyline = new TCurlyLine("
348  <<fX1<<","<<fY1<<","<<fX2<<","<<fY2<<","
349  <<fWaveLength<<","<<fAmplitude<<");"<<std::endl;
350  if (!fIsCurly) {
351  out<<" curlyline->SetWavy();"<<std::endl;
352  }
353  SaveLineAttributes(out,"curlyline",1,1,1);
354  out<<" curlyline->Draw();"<<std::endl;
355 }
356
357 ////////////////////////////////////////////////////////////////////////////////
358 /// Set curly.
359
361 {
362  fIsCurly = kTRUE;
363  Build();
364 }
365
366 ////////////////////////////////////////////////////////////////////////////////
367 /// Set wavy.
368
369 void TCurlyLine::SetWavy()
370 {
371  fIsCurly = kFALSE;
372  Build();
373 }
374
375 ////////////////////////////////////////////////////////////////////////////////
376 /// Set wave length.
377
379 {
380  fWaveLength = x;
381  Build();
382 }
383
384 ////////////////////////////////////////////////////////////////////////////////
385 /// Set amplitude.
386
388 {
389  fAmplitude = x;
390  Build();
391 }
392
393 ////////////////////////////////////////////////////////////////////////////////
394 /// Set start point.
395
397 {
398  fX1 = x;
399  fY1 = y;
400  Build();
401 }
402
403 ////////////////////////////////////////////////////////////////////////////////
404 /// Set end point.
405
407 {
408  fX2 = x;
409  fY2 = y;
410  Build();
411 }
412
413 ////////////////////////////////////////////////////////////////////////////////
414 /// Set default wave length.
415
417 {
418  fgDefaultWaveLength = WaveLength;
419 }
420
421 ////////////////////////////////////////////////////////////////////////////////
422 /// Set default amplitude.
423
425 {
426  fgDefaultAmplitude = Amplitude;
427 }
428
429 ////////////////////////////////////////////////////////////////////////////////
430 /// Set default "IsCurly".
431
433 {
434  fgDefaultIsCurly = IsCurly;
435 }
436
437 ////////////////////////////////////////////////////////////////////////////////
438 /// Get default wave length.
439
441 {
442  return fgDefaultWaveLength;
443 }
444
445 ////////////////////////////////////////////////////////////////////////////////
446 /// Get default amplitude.
447
449 {
450  return fgDefaultAmplitude;
451 }
452
453 ////////////////////////////////////////////////////////////////////////////////
454 /// Get default "IsCurly".
455
457 {
458  return fgDefaultIsCurly;
459 }
460
461 ////////////////////////////////////////////////////////////////////////////////
462 /// Return the bounding Box of the CurlyLine
463
465 {
466  Rectangle_t BBox;
467  Int_t px1, py1, px2, py2;
472
473  Int_t tmp;
474  if (px1>px2) { tmp = px1; px1 = px2; px2 = tmp;}
475  if (py1>py2) { tmp = py1; py1 = py2; py2 = tmp;}
476
477  BBox.fX = px1;
478  BBox.fY = py1;
479  BBox.fWidth = px2-px1;
480  BBox.fHeight = py2-py1;
481
482  return (BBox);
483 }
484
485 ////////////////////////////////////////////////////////////////////////////////
486 /// Return the center of the BoundingBox as TPoint in pixels
487
489 {
490  TPoint p;
493  return(p);
494 }
495
496 ////////////////////////////////////////////////////////////////////////////////
497 /// Set center of the BoundingBox
498
499 void TCurlyLine::SetBBoxCenter(const TPoint &p)
500 {
503  Double_t x1, x2, y1, y2;
504  x1 = x2 = y1 = y2 = 0;
505
506  if (fX2>fX1) {
509  }
510  else {
513  }
514  if (fY2>fY1) {
517  }
518  else {
521  }
522  this->SetStartPoint(x1, y1);
523  this->SetEndPoint(x2, y2);
524 }
525
526 ////////////////////////////////////////////////////////////////////////////////
527 /// Set X coordinate of the center of the BoundingBox
528
530 {
532  if (fX2>fX1) {
535  }
536  else {
539  }
540 }
541
542 ////////////////////////////////////////////////////////////////////////////////
543 /// Set Y coordinate of the center of the BoundingBox
544
546 {
548  if (fY2>fY1) {
551  }
552  else {
555  }
556 }
557
558 ////////////////////////////////////////////////////////////////////////////////
559 /// Set left hand side of BoundingBox to a value
560 /// (resize in x direction on left)
561
562 void TCurlyLine::SetBBoxX1(const Int_t x)
563 {
564  if (fX2>fX1)
566  else
568 }
569
570 ////////////////////////////////////////////////////////////////////////////////
571 /// Set right hands ide of BoundingBox to a value
572 /// (resize in x direction on right)
573
574 void TCurlyLine::SetBBoxX2(const Int_t x)
575 {
576  if (fX2>fX1)
578  else
580 }
581
582 ////////////////////////////////////////////////////////////////////////////////
583 /// Set top of BoundingBox to a value (resize in y direction on top)
584
585 void TCurlyLine::SetBBoxY1(const Int_t y)
586 {
587  if (fY2>fY1)
589  else
591 }
592
593 ////////////////////////////////////////////////////////////////////////////////
594 /// Set bottom of BoundingBox to a value
595 /// (resize in y direction on bottom)
596
597 void TCurlyLine::SetBBoxY2(const Int_t y)
598 {
599  if (fY2>fY1)
601  else
603 }
UShort_t fWidth
Definition: GuiTypes.h:364
static Double_t GetDefaultWaveLength()
Get default wave length.
Definition: TCurlyLine.cxx:441
virtual Rectangle_t GetBBox()
Return the bounding Box of the CurlyLine.
Definition: TCurlyLine.cxx:465
void SetX(SCoord_t x)
Definition: TPoint.h:51
Short_t fY
Definition: GuiTypes.h:363
static Bool_t GetDefaultIsCurly()
Get default "IsCurly".
Definition: TCurlyLine.cxx:457
UShort_t fHeight
Definition: GuiTypes.h:364
Double_t * GetX() const
Definition: TPolyLine.h:62
TCurlyLine()
Default constructor.
Definition: TCurlyLine.cxx:47
Bool_t fIsCurly
true: Gluon, false: Gamma
Definition: TCurlyLine.h:40
Double_t fY2
end y
Definition: TCurlyLine.h:36
const char Option_t
Definition: RtypesCore.h:62
virtual void SetBBoxCenterX(const Int_t x)
Set X coordinate of the center of the BoundingBox.
Definition: TCurlyLine.cxx:530
TH1 * h
Definition: legend2.C:5
Double_t fX1
start x, center for arc
Definition: TCurlyLine.h:33
#define gROOT
Definition: TROOT.h:364
Double_t fY1
start y, center for arc
Definition: TCurlyLine.h:34
static void SetDefaultIsCurly(Bool_t IsCurly)
Set default "IsCurly".
Definition: TCurlyLine.cxx:433
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:170
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
SCoord_t GetY() const
Definition: TPoint.h:50
SCoord_t GetX() const
Definition: TPoint.h:49
virtual void Modify()
Change current line attributes if necessary.
Definition: TAttLine.cxx:232
const char * Class
Definition: TXMLSetup.cxx:64
void SetY(SCoord_t y)
Definition: TPoint.h:52
Short_t Abs(Short_t d)
Definition: TMathBase.h:110
static const double x2[5]
Double_t x[n]
Definition: legend1.C:17
virtual void SetWaveLength(Double_t WaveLength)
Set wave length.
Definition: TCurlyLine.cxx:379
virtual void SetStartPoint(Double_t x1, Double_t y1)
Set start point.
Definition: TCurlyLine.cxx:397
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:260
Implements curly or wavy polylines used to draw Feynman diagrams.
Definition: TCurlyLine.h:30
static double p2(double t, double a, double b, double c)
virtual void SavePrimitive(std::ostream &out, Option_t *="")
Save primitive as a C++ statement(s) on output stream out.
Definition: TCurlyLine.cxx:341
virtual void SetCurly()
Set curly.
Definition: TCurlyLine.cxx:361
Double_t ATan2(Double_t, Double_t)
Definition: TMath.h:454
virtual void SetBBoxCenter(const TPoint &p)
Set center of the BoundingBox.
Definition: TCurlyLine.cxx:500
virtual void SetBBoxX2(const Int_t x)
Set right hands ide of BoundingBox to a value (resize in x direction on right)
Definition: TCurlyLine.cxx:575
Short_t fX
Definition: GuiTypes.h:363
Int_t fNsteps
used internally (controls precision)
Definition: TCurlyLine.h:39
Definition: TPoint.h:33
Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute distance from point px,py to a line.
Definition: TCurlyLine.cxx:170
static Double_t GetDefaultAmplitude()
Get default amplitude.
Definition: TCurlyLine.cxx:449
virtual void SetEndPoint(Double_t x2, Double_t y2)
Set end point.
Definition: TCurlyLine.cxx:407
Double_t * GetY() const
Definition: TPolyLine.h:63
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:488
static Double_t fgDefaultWaveLength
default wavelength
Definition: TCurlyLine.h:42
void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Execute action corresponding to one event.
Definition: TCurlyLine.cxx:186
static double p1(double t, double a, double b)
virtual void SetPolyLine(Int_t n)
Resize this polyline to size n.
Definition: TPolyLine.cxx:670
static void SetDefaultAmplitude(Double_t Amplitude)
Set default amplitude.
Definition: TCurlyLine.cxx:425
#define gVirtualX
Definition: TVirtualX.h:362
Double_t Cos(Double_t)
Definition: TMath.h:424
Double_t Pi()
Definition: TMath.h:44
static Bool_t fgDefaultIsCurly
default curly type
Definition: TCurlyLine.h:44
static const double x1[5]
#define ClassImp(name)
Definition: Rtypes.h:279
double Double_t
Definition: RtypesCore.h:55
virtual void SetWavy()
Set wavy.
Definition: TCurlyLine.cxx:370
virtual TPoint GetBBoxCenter()
Return the center of the BoundingBox as TPoint in pixels.
Definition: TCurlyLine.cxx:489
Double_t y[n]
Definition: legend1.C:17
Int_t DistancetoLine(Int_t px, Int_t py, Double_t xp1, Double_t yp1, Double_t xp2, Double_t yp2)
Compute distance from point px,py to a line.
Definition: TAttLine.cxx:196
static void SetDefaultWaveLength(Double_t WaveLength)
Set default wave length.
Definition: TCurlyLine.cxx:417
Double_t fX2
end x
Definition: TCurlyLine.h:35
Double_t fWaveLength
wavelength of sinusoid in percent of pad height
Definition: TCurlyLine.h:37
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:202
virtual void SetBBoxY1(const Int_t y)
Set top of BoundingBox to a value (resize in y direction on top)
Definition: TCurlyLine.cxx:586
Double_t fAmplitude
amplitude of sinusoid in percent of pad height
Definition: TCurlyLine.h:38
Double_t Sin(Double_t)
Definition: TMath.h:421
virtual void SetBBoxCenterY(const Int_t y)
Set Y coordinate of the center of the BoundingBox.
Definition: TCurlyLine.cxx:546
virtual void SetBBoxX1(const Int_t x)
Set left hand side of BoundingBox to a value (resize in x direction on left)
Definition: TCurlyLine.cxx:563
Double_t Sqrt(Double_t x)
Definition: TMath.h:464
const Bool_t kTRUE
Definition: Rtypes.h:91
virtual void SetBBoxY2(const Int_t y)
Set bottom of BoundingBox to a value (resize in y direction on bottom)
Definition: TCurlyLine.cxx:598
virtual void SetAmplitude(Double_t x)
Set amplitude.
Definition: TCurlyLine.cxx:388
virtual void Build()
Create a curly (Gluon) or wavy (Gamma) line.
Definition: TCurlyLine.cxx:78
static Double_t fgDefaultAmplitude
default amplitude
Definition: TCurlyLine.h:43