Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TCurlyLine.cxx
Go to the documentation of this file.
1// @(#)root/graf:$Id$
2// Author: Otto Schaile 20/11/99
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/** \class TCurlyLine
13\ingroup BasicGraphics
14
15Implements curly or wavy polylines used to draw Feynman diagrams.
16
17Amplitudes and wavelengths may be specified in the constructors,
18via commands or interactively from popup menus.
19The class make use of TPolyLine by inheritance, ExecuteEvent methods
20are highly inspired from the methods used in TPolyLine and TArc.
21The picture below has been generated by the tutorial feynman.
22
23Begin_Macro(source)
24../../../tutorials/visualisation/graphics/feynman.C
25End_Macro
26*/
27
28#include "TCurlyLine.h"
29#include "TVirtualPad.h"
30#include "TLineInteractive.h"
31#include "TROOT.h"
32#include "TMath.h"
33#include "TPoint.h"
34
35#include <iostream>
36
40
41
42////////////////////////////////////////////////////////////////////////////////
43/// Default constructor.
44
46{
47 fX1 = 0.;
48 fY1 = 0.;
49 fX2 = 0.;
50 fY2 = 0.;
51 fWaveLength = 0.;
52 fAmplitude = 0.;
54 fNsteps = 0;
55}
56
57////////////////////////////////////////////////////////////////////////////////
58/// Create a new TCurlyLine with starting point (x1, y1), end point (x2,y2).
59/// The wavelength and amplitude are given in percent of the pad height.
60
72
73////////////////////////////////////////////////////////////////////////////////
74/// Create a curly (Gluon) or wavy (Gamma) line.
75
77{
78 Double_t pixeltoX = 1;
79 Double_t pixeltoY = 1;
80
81 Double_t wavelengthPix,amplitudePix, lengthPix, hPix;
82 Double_t px1, py1, px2, py2;
83
84 if (gPad) {
85 Double_t pxrange = gPad->GetPadWidth();
86 Double_t pyrange = -1. * gPad->GetPadHeight();
87 Double_t xrange = gPad->GetX2() - gPad->GetX1();
88 Double_t yrange = gPad->GetY2() - gPad->GetY1();
89 pixeltoX = xrange / pxrange;
90 pixeltoY = yrange / pyrange;
91 hPix = TMath::Max(pxrange, -pyrange);
92 px1 = gPad->XtoAbsPixel(fX1);
93 py1 = gPad->YtoAbsPixel(fY1);
94 px2 = gPad->XtoAbsPixel(fX2);
95 py2 = gPad->YtoAbsPixel(fY2);
96 lengthPix = TMath::Sqrt((px2-px1)*(px2-px1) + (py1-py2)*(py1-py2));
97 wavelengthPix = hPix*fWaveLength;
98 amplitudePix = hPix*fAmplitude;
99 } else {
100 wavelengthPix = fWaveLength;
101 amplitudePix = fAmplitude;
102 px1 = fX1;
103 py1 = fY1;
104 px2 = fX2;
105 py2 = fY2;
106 lengthPix = TMath::Sqrt((px2-px1)*(px2-px1) + (py1-py2)*(py1-py2));
107 }
108 // construct the curly / wavy line in pixel coordinates at angle 0
109 Double_t anglestep = 40;
110 Double_t phimaxle = TMath::Pi() * 2. / anglestep ;
111 Double_t dx = wavelengthPix / 40;
112 Double_t len2pi = dx * anglestep;
113
114 // make sure there is a piece of straight line a both ends
115
116 Double_t lengthcycle = 0.5 * len2pi + 2 * amplitudePix;
117 // if (fIsCurly) lengthcycle += amplitudePix;
118 Int_t nperiods = (Int_t)((lengthPix - lengthcycle) / len2pi);
119 Double_t restlength = 0.5 * (lengthPix - nperiods * len2pi - lengthcycle);
120 fNsteps = (Int_t)(anglestep * nperiods + anglestep / 2 + 4);
121 if (fNsteps < 2) fNsteps = 2;
123 Double_t *xv = GetX();
124 Double_t *yv = GetY();
125 xv[0] = 0; yv[0] = 0;
126 xv[1] = restlength; yv[1] = 0;
127 Double_t phase = 1.5 * TMath::Pi();
128 Double_t x0 = amplitudePix + restlength;
129 Int_t i;
130 for(i = 2; i < fNsteps-1; i++){
131 // distinguish between curly and wavy
132 if (fIsCurly) xv[i] = x0 + amplitudePix * TMath::Sin(phase);
133 else xv[i] = x0;
134 yv[i] = amplitudePix*TMath::Cos(phase);
135 phase += phimaxle;
136 x0 += dx;
137 }
138 xv[fNsteps-1] = lengthPix; yv[fNsteps-1] = 0;
139
140 if (InheritsFrom("TCurlyArc")) return; // called by TCurlyArc
141
142 // rotate object and transform back to user coordinates
143 Double_t angle = TMath::ATan2(py2-py1, px2-px1);
144 if (angle < 0) angle += 2*TMath::Pi();
145
146 Double_t cosang = TMath::Cos(angle);
147 Double_t sinang = TMath::Sin(angle);
148 Double_t xx, yy;
149
150 for(i = 0; i < fNsteps; i++){
151 xx = xv[i] * cosang - yv[i] * sinang;
152 yy = xv[i] * sinang + yv[i] * cosang;
153 if (gPad) {
154 xx *= pixeltoX;
155 yy *= pixeltoY;
156 }
157 xv[i] = xx + fX1;
158 yv[i] = yy + fY1;
159 }
160 if (gPad) gPad->Modified();
161}
162
163////////////////////////////////////////////////////////////////////////////////
164/// Compute distance from point px,py to a line.
165
170
172public:
174
175 void Apply(TCurlyLine *l, Bool_t usenew = kTRUE)
176 {
177 l->SetStartPoint(usenew ? newX1 : oldX1, usenew ? newY1 : oldY1);
178 l->SetEndPoint(usenew ? newX2 : oldX2, usenew ? newY2 : oldY2);
179 }
180};
181
182////////////////////////////////////////////////////////////////////////////////
183/// Execute action corresponding to one event.
184///
185/// This member function is called when a TCurlyLine is clicked with the locator
186///
187/// If Left button clicked on one of the line end points, this point
188/// follows the cursor until button is released.
189///
190/// if Middle button clicked, the line is moved parallel to itself
191/// until the button is released.
192
194{
195 if (!gPad || !gPad->IsEditable()) return;
196
197 auto &parent = *gPad;
198
199 Bool_t opaque = parent.OpaqueMoving();
200
201 auto inter = parent.GetInteractive<TCurlyLineInteractive>(this);
202
203 switch (event) {
204
205 case kArrowKeyPress:
206 case kButton1Down:
207 inter = parent.MakeInteractive<TCurlyLineInteractive>(this, GetStartX(), GetStartY(), GetEndX(), GetEndY());
208 // No break !!!
209
210 case kMouseMotion:
211 if (inter)
212 inter->SelectPoint(parent, px, py);
213 break;
214
215 case kArrowKeyRelease:
216 case kButton1Motion:
217 if (!inter)
218 return;
219 inter->ChangeCoordinate(parent, px, py);
220 if (!opaque) {
221 TAttLine::ModifyOn(parent);
222 inter->PaintLine(parent);
223 } else {
224 inter->Apply(this);
225 char guide = inter->GetGuideChar();
226 if (guide)
227 parent.ShowGuidelines(this, event, guide, true);
228 parent.Modified();
229 }
230 parent.UpdateAsync();
231 break;
232
233 case kButton1Up:
234 if (gROOT->IsEscaped()) {
235 gROOT->SetEscape(kFALSE);
236 if (opaque && inter) {
237 inter->Apply(this, kFALSE);
238 parent.Modified();
239 parent.ShowGuidelines(this, event);
240 }
241 } else if (opaque) {
242 parent.ShowGuidelines(this, event);
243 } else if (inter) {
244 inter->Apply(this);
245 parent.Modified();
246 }
247 parent.UpdateAsync();
248 parent.FreeInteractive(this);
249 break;
250 }
251}
252
253////////////////////////////////////////////////////////////////////////////////
254/// Save primitive as a C++ statement(s) on output stream out
255
257{
258 SavePrimitiveConstructor(out, Class(), "curlyline",
259 TString::Format("%g, %g, %g, %g, %g, %g", fX1, fY1, fX2, fY2, fWaveLength, fAmplitude));
260
261 SaveLineAttributes(out, "curlyline", 1, 1, 1);
262
263 if (!fIsCurly)
264 out << " curlyline->SetWavy();\n";
265
266 SavePrimitiveDraw(out, "curlyline", option);
267}
268
269////////////////////////////////////////////////////////////////////////////////
270/// Set curly.
271
273{
274 fIsCurly = kTRUE;
275 Build();
276}
277
278////////////////////////////////////////////////////////////////////////////////
279/// Set wavy.
280
282{
284 Build();
285}
286
287////////////////////////////////////////////////////////////////////////////////
288/// Set wave length.
289
295
296////////////////////////////////////////////////////////////////////////////////
297/// Set amplitude.
298
300{
301 fAmplitude = x;
302 Build();
303}
304
305////////////////////////////////////////////////////////////////////////////////
306/// Set start point.
307
309{
310 fX1 = x;
311 fY1 = y;
312 Build();
313}
314
315////////////////////////////////////////////////////////////////////////////////
316/// Set end point.
317
319{
320 fX2 = x;
321 fY2 = y;
322 Build();
323}
324
325////////////////////////////////////////////////////////////////////////////////
326/// Set default wave length.
327
329{
330 fgDefaultWaveLength = WaveLength;
331}
332
333////////////////////////////////////////////////////////////////////////////////
334/// Set default amplitude.
335
337{
338 fgDefaultAmplitude = Amplitude;
339}
340
341////////////////////////////////////////////////////////////////////////////////
342/// Set default "IsCurly".
343
345{
346 fgDefaultIsCurly = IsCurly;
347}
348
349////////////////////////////////////////////////////////////////////////////////
350/// Get default wave length.
351
356
357////////////////////////////////////////////////////////////////////////////////
358/// Get default amplitude.
359
364
365////////////////////////////////////////////////////////////////////////////////
366/// Get default "IsCurly".
367
372
373////////////////////////////////////////////////////////////////////////////////
374/// Return the bounding Box of the CurlyLine
375
377{
378 Rectangle_t bbox{0,0,0,0};
379 if (gPad) {
380 Int_t px1 = gPad->XtoPixel(fX1);
381 Int_t px2 = gPad->XtoPixel(fX2);
382 Int_t py1 = gPad->YtoPixel(fY1);
383 Int_t py2 = gPad->YtoPixel(fY2);
384
385 if (px1 > px2)
386 std::swap(px1, px2);
387 if (py1 > py2)
388 std::swap(py1, py2);
389
390 bbox.fX = px1;
391 bbox.fY = py1;
392 bbox.fWidth = px2 - px1;
393 bbox.fHeight = py2 - py1;
394 }
395 return bbox;
396}
397
398////////////////////////////////////////////////////////////////////////////////
399/// Set X coordinate of the center of the BoundingBox
400
402{
403 Double_t w2 = 0.5 * (fX2 - fX1);
404 Double_t midx = GetXCoord(x);
405 SetStartPoint(midx - w2, fY1);
406 SetEndPoint(midx + w2, fY2);
407}
408
409////////////////////////////////////////////////////////////////////////////////
410/// Set Y coordinate of the center of the BoundingBox
411
413{
414 Double_t h2 = 0.5 * (fY2 - fY1);
415 Double_t midy = GetYCoord(y);
416 SetStartPoint(fX1, midy - h2);
417 SetEndPoint(fX2, midy + h2);
418}
419
420////////////////////////////////////////////////////////////////////////////////
421/// Set left hand side of BoundingBox to a value
422/// (resize in x direction on left)
423
425{
426 if (fX2 > fX1)
428 else
430}
431
432////////////////////////////////////////////////////////////////////////////////
433/// Set right hands ide of BoundingBox to a value
434/// (resize in x direction on right)
435
437{
438 if (fX2 > fX1)
440 else
442}
443
444////////////////////////////////////////////////////////////////////////////////
445/// Set top of BoundingBox to a value (resize in y direction on top)
446
448{
449 if (fY2 > fY1)
451 else
453}
454
455////////////////////////////////////////////////////////////////////////////////
456/// Set bottom of BoundingBox to a value
457/// (resize in y direction on bottom)
458
460{
461 if (fY2 > fY1)
463 else
465}
@ 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
cudaEvent_t event
bool Bool_t
Boolean (0=false, 1=true) (bool)
Definition RtypesCore.h:78
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:60
constexpr Bool_t kFALSE
Definition RtypesCore.h:109
double Double_t
Double 8 bytes.
Definition RtypesCore.h:74
constexpr Bool_t kTRUE
Definition RtypesCore.h:108
const char Option_t
Option string (const char)
Definition RtypesCore.h:81
Option_t Option_t option
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:417
#define gPad
Double_t GetYCoord(const Int_t y, Bool_t is_ndc=kFALSE, Bool_t is_absolute=kFALSE)
Can return ndc or normal values Also one can specify to use absolute coordinates for input parameter ...
Double_t GetXCoord(const Int_t x, Bool_t is_ndc=kFALSE, Bool_t is_absolute=kFALSE)
Return user X coordinate for pixel X value Can return ndc or normal values Also one can specify to us...
virtual void ModifyOn(TVirtualPad &pad)
Change current line attributes on specified pad.
Definition TAttLine.cxx:255
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:210
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:289
void Apply(TCurlyLine *l, Bool_t usenew=kTRUE)
Implements curly or wavy polylines used to draw Feynman diagrams.
Definition TCurlyLine.h:19
TCurlyLine()
Default constructor.
virtual void SetWaveLength(Double_t WaveLength)
Set wave length.
virtual void SetCurly()
Set curly.
static TClass * Class()
Double_t fY1
start y, center for arc
Definition TCurlyLine.h:23
virtual void SetAmplitude(Double_t x)
Set amplitude.
Double_t fWaveLength
wavelength of sinusoid in percent of pad height
Definition TCurlyLine.h:26
Double_t fAmplitude
amplitude of sinusoid in percent of pad height
Definition TCurlyLine.h:27
void SetBBoxY1(const Int_t y) override
Set top of BoundingBox to a value (resize in y direction on top)
virtual void SetStartPoint(Double_t x1, Double_t y1)
Set start point.
void SetBBoxX2(const Int_t x) override
Set right hands ide of BoundingBox to a value (resize in x direction on right)
Int_t fNsteps
used internally (controls precision)
Definition TCurlyLine.h:28
void SetBBoxY2(const Int_t y) override
Set bottom of BoundingBox to a value (resize in y direction on bottom)
Rectangle_t GetBBox() override
Return the bounding Box of the CurlyLine.
Double_t GetEndY() const
Definition TCurlyLine.h:50
static Double_t GetDefaultWaveLength()
Get default wave length.
static Bool_t GetDefaultIsCurly()
Get default "IsCurly".
virtual void Build()
Create a curly (Gluon) or wavy (Gamma) line.
void SavePrimitive(std::ostream &out, Option_t *="") override
Save primitive as a C++ statement(s) on output stream out.
static void SetDefaultAmplitude(Double_t Amplitude)
Set default amplitude.
Double_t GetStartY() const
Definition TCurlyLine.h:49
static void SetDefaultWaveLength(Double_t WaveLength)
Set default wave length.
static Bool_t fgDefaultIsCurly
default curly type
Definition TCurlyLine.h:33
Double_t fY2
end y
Definition TCurlyLine.h:25
static Double_t GetDefaultAmplitude()
Get default amplitude.
virtual void SetEndPoint(Double_t x2, Double_t y2)
Set end point.
void SetBBoxX1(const Int_t x) override
Set left hand side of BoundingBox to a value (resize in x direction on left)
Double_t fX1
start x, center for arc
Definition TCurlyLine.h:22
static Double_t fgDefaultWaveLength
default wavelength
Definition TCurlyLine.h:31
void SetBBoxCenterX(const Int_t x) override
Set X coordinate of the center of the BoundingBox.
static void SetDefaultIsCurly(Bool_t IsCurly)
Set default "IsCurly".
virtual void SetWavy()
Set wavy.
static Double_t fgDefaultAmplitude
default amplitude
Definition TCurlyLine.h:32
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
Compute distance from point px,py to a line.
Double_t GetStartX() const
Definition TCurlyLine.h:47
Double_t fX2
end x
Definition TCurlyLine.h:24
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
Execute action corresponding to one event.
Bool_t fIsCurly
true: Gluon, false: Gamma
Definition TCurlyLine.h:29
Double_t GetEndX() const
Definition TCurlyLine.h:48
void SetBBoxCenterY(const Int_t y) override
Set Y coordinate of the center of the BoundingBox.
TLineInteractive(Double_t x1, Double_t y1, Double_t x2, Double_t y2, Bool_t ndc=kFALSE)
void SelectPoint(TVirtualPad &parent, Int_t px, Int_t py)
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:548
static void SavePrimitiveDraw(std::ostream &out, const char *variable_name, Option_t *option=nullptr)
Save invocation of primitive Draw() method Skipped if option contains "nodraw" string.
Definition TObject.cxx:844
static void SavePrimitiveConstructor(std::ostream &out, TClass *cl, const char *variable_name, const char *constructor_agrs="", Bool_t empty_line=kTRUE)
Save object constructor in the output stream "out".
Definition TObject.cxx:776
Double_t * GetX() const
Definition TPolyLine.h:54
Double_t * GetY() const
Definition TPolyLine.h:55
virtual void SetPolyLine(Int_t n)
Resize this polyline to size n.
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2460
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:249
Double_t ATan2(Double_t y, Double_t x)
Returns the principal value of the arc tangent of y/x, expressed in radians.
Definition TMath.h:659
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:675
Double_t Cos(Double_t)
Returns the cosine of an angle of x radians.
Definition TMath.h:607
constexpr Double_t Pi()
Definition TMath.h:40
Double_t Sin(Double_t)
Returns the sine of an angle of x radians.
Definition TMath.h:601
Rectangle structure (maps to the X11 XRectangle structure)
Definition GuiTypes.h:362
TLine l
Definition textangle.C:4