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 "TVirtualPadPainter.h"
31#include "TMath.h"
32#include "TPoint.h"
33
34#include <iostream>
35
39
40
41////////////////////////////////////////////////////////////////////////////////
42/// Default constructor.
43
45{
46 fX1 = 0.;
47 fY1 = 0.;
48 fX2 = 0.;
49 fY2 = 0.;
50 fWaveLength = 0.;
51 fAmplitude = 0.;
53 fNsteps = 0;
54}
55
56////////////////////////////////////////////////////////////////////////////////
57/// Create a new TCurlyLine with starting point (x1, y1), end point (x2,y2).
58/// The wavelength and amplitude are given in percent of the pad height.
59
71
72////////////////////////////////////////////////////////////////////////////////
73/// Create a curly (Gluon) or wavy (Gamma) line.
74
76{
79
81 Double_t px1, py1, px2, py2;
82
83 if (gPad) {
84 Double_t pxrange = gPad->GetPadWidth();
85 Double_t pyrange = -1. * gPad->GetPadHeight();
86 Double_t xrange = gPad->GetX2() - gPad->GetX1();
87 Double_t yrange = gPad->GetY2() - gPad->GetY1();
91 px1 = gPad->XtoAbsPixel(fX1);
92 py1 = gPad->YtoAbsPixel(fY1);
93 px2 = gPad->XtoAbsPixel(fX2);
94 py2 = gPad->YtoAbsPixel(fY2);
95 lengthPix = TMath::Sqrt((px2-px1)*(px2-px1) + (py1-py2)*(py1-py2));
98 } else {
101 px1 = fX1;
102 py1 = fY1;
103 px2 = fX2;
104 py2 = fY2;
105 lengthPix = TMath::Sqrt((px2-px1)*(px2-px1) + (py1-py2)*(py1-py2));
106 }
107 // construct the curly / wavy line in pixel coordinates at angle 0
108 Double_t anglestep = 40;
112
113 // make sure there is a piece of straight line a both ends
114
116 // if (fIsCurly) lengthcycle += amplitudePix;
119 fNsteps = (Int_t)(anglestep * nperiods + anglestep / 2 + 4);
120 if (fNsteps < 2) fNsteps = 2;
122 Double_t *xv = GetX();
123 Double_t *yv = GetY();
124 xv[0] = 0; yv[0] = 0;
125 xv[1] = restlength; yv[1] = 0;
126 Double_t phase = 1.5 * TMath::Pi();
128 Int_t i;
129 for(i = 2; i < fNsteps-1; i++){
130 // distinguish between curly and wavy
131 if (fIsCurly) xv[i] = x0 + amplitudePix * TMath::Sin(phase);
132 else xv[i] = x0;
134 phase += phimaxle;
135 x0 += dx;
136 }
137 xv[fNsteps-1] = lengthPix; yv[fNsteps-1] = 0;
138
139 if (InheritsFrom("TCurlyArc")) return; // called by TCurlyArc
140
141 // rotate object and transform back to user coordinates
142 Double_t angle = TMath::ATan2(py2-py1, px2-px1);
143 if (angle < 0) angle += 2*TMath::Pi();
144
147 Double_t xx, yy;
148
149 for(i = 0; i < fNsteps; i++){
150 xx = xv[i] * cosang - yv[i] * sinang;
151 yy = xv[i] * sinang + yv[i] * cosang;
152 if (gPad) {
153 xx *= pixeltoX;
154 yy *= pixeltoY;
155 }
156 xv[i] = xx + fX1;
157 yv[i] = yy + fY1;
158 }
159 if (gPad) gPad->Modified();
160}
161
162////////////////////////////////////////////////////////////////////////////////
163/// Compute distance from point px,py to a line.
164
169
170////////////////////////////////////////////////////////////////////////////////
171/// Execute action corresponding to one event.
172///
173/// This member function is called when a TCurlyLine is clicked with the locator
174///
175/// If Left button clicked on one of the line end points, this point
176/// follows the cursor until button is released.
177///
178/// if Middle button clicked, the line is moved parallel to itself
179/// until the button is released.
180
182{
183 if (!gPad || !gPad->IsEditable()) return;
184
185 constexpr Int_t kMaxDiff = 20;
186 static Int_t sdx = 0, sdy = 0, selectPoint;
187
188 auto &parent = *gPad;
189
190 Bool_t opaque = parent.OpaqueMoving();
191
192 auto paint = [this, &parent]() {
193 auto pp = parent.GetPainter();
194 pp->SetAttLine(*this);
195 pp->DrawLine(parent.XtoPad(fX1), parent.YtoPad(fY1), parent.XtoPad(fX2), parent.YtoPad(fY2));
196 };
197
198 auto set_coord = [this](Int_t _x1, Int_t _y1, Int_t _x2, Int_t _y2) {
199 if (selectPoint & 1) {
200 fX1 = GetXCoord(_x1, kFALSE, kTRUE);
202 }
203 if (selectPoint & 2) {
204 fX2 = GetXCoord(_x2, kFALSE, kTRUE);
206 }
207 };
208
209 Int_t px1 = parent.XtoAbsPixel(parent.XtoPad(fX1));
210 Int_t py1 = parent.YtoAbsPixel(parent.YtoPad(fY1));
211 Int_t px2 = parent.XtoAbsPixel(parent.XtoPad(fX2));
212 Int_t py2 = parent.YtoAbsPixel(parent.YtoPad(fY2));
213
214 switch (event) {
215
216 case kArrowKeyPress:
217 case kButton1Down:
218
219 // No break !!!
220
221 case kMouseMotion:
222
223 if (abs(px1 - px) + abs(py1 - py) < kMaxDiff) {
224 selectPoint = 1;
225 parent.SetCursor(kPointer);
226 } else if (abs(px2 - px) + abs(py2 - py) < kMaxDiff) {
227 selectPoint = 2;
228 parent.SetCursor(kPointer);
229 } else {
230 selectPoint = 3;
231 sdx = px1 - px;
232 sdy = py1 - py;
233 parent.SetCursor(kMove);
234 }
235
236 break;
237
238 case kArrowKeyRelease:
239 case kButton1Motion:
240 if (!opaque)
241 paint();
242 if (selectPoint == 1) {
243 set_coord(px, py, 0, 0);
244 } else if (selectPoint == 2) {
245 set_coord(0, 0, px, py);
246 } else if (selectPoint == 3) {
247 set_coord(px + sdx, py + sdy, px + sdx + px2 - px1, py + sdy + py2 - py1);
248 }
249 if (!opaque)
250 paint();
251 else {
252 char guide = selectPoint == 3 ? 'i' : '\0';
253 if ((selectPoint == 1) || (selectPoint == 2)) {
254 static const char GUIDES[2][2][2] = {
255 { { '4', '1' }, { '3', '2' } },
256 { { '2', '3' }, { '1', '4' } }
257 };
258 int x_idx = fX1 > fX2 ? 1 : 0;
259 int y_idx = fY1 > fY2 ? 1 : 0;
261 }
262 if (guide)
263 parent.ShowGuidelines(this, event, guide, true);
264
265 Build();
266 parent.ModifiedUpdate();
267 }
268 break;
269
270 case kButton1Up:
271
272 if (opaque)
273 parent.ShowGuidelines(this, event);
274 else {
275 Build();
276 parent.ModifiedUpdate();
277 }
278 }
279}
280
281////////////////////////////////////////////////////////////////////////////////
282/// Save primitive as a C++ statement(s) on output stream out
283
285{
286 SavePrimitiveConstructor(out, Class(), "curlyline",
287 TString::Format("%g, %g, %g, %g, %g, %g", fX1, fY1, fX2, fY2, fWaveLength, fAmplitude));
288
289 SaveLineAttributes(out, "curlyline", 1, 1, 1);
290
291 if (!fIsCurly)
292 out << " curlyline->SetWavy();\n";
293
294 SavePrimitiveDraw(out, "curlyline", option);
295}
296
297////////////////////////////////////////////////////////////////////////////////
298/// Set curly.
299
301{
302 fIsCurly = kTRUE;
303 Build();
304}
305
306////////////////////////////////////////////////////////////////////////////////
307/// Set wavy.
308
310{
312 Build();
313}
314
315////////////////////////////////////////////////////////////////////////////////
316/// Set wave length.
317
323
324////////////////////////////////////////////////////////////////////////////////
325/// Set amplitude.
326
328{
329 fAmplitude = x;
330 Build();
331}
332
333////////////////////////////////////////////////////////////////////////////////
334/// Set start point.
335
337{
338 fX1 = x;
339 fY1 = y;
340 Build();
341}
342
343////////////////////////////////////////////////////////////////////////////////
344/// Set end point.
345
347{
348 fX2 = x;
349 fY2 = y;
350 Build();
351}
352
353////////////////////////////////////////////////////////////////////////////////
354/// Set default wave length.
355
360
361////////////////////////////////////////////////////////////////////////////////
362/// Set default amplitude.
363
368
369////////////////////////////////////////////////////////////////////////////////
370/// Set default "IsCurly".
371
376
377////////////////////////////////////////////////////////////////////////////////
378/// Get default wave length.
379
384
385////////////////////////////////////////////////////////////////////////////////
386/// Get default amplitude.
387
392
393////////////////////////////////////////////////////////////////////////////////
394/// Get default "IsCurly".
395
400
401////////////////////////////////////////////////////////////////////////////////
402/// Return the bounding Box of the CurlyLine
403
405{
406 Rectangle_t bbox{0,0,0,0};
407 if (gPad) {
408 Int_t px1 = gPad->XtoPixel(fX1);
409 Int_t px2 = gPad->XtoPixel(fX2);
410 Int_t py1 = gPad->YtoPixel(fY1);
411 Int_t py2 = gPad->YtoPixel(fY2);
412
413 if (px1 > px2)
414 std::swap(px1, px2);
415 if (py1 > py2)
416 std::swap(py1, py2);
417
418 bbox.fX = px1;
419 bbox.fY = py1;
420 bbox.fWidth = px2 - px1;
421 bbox.fHeight = py2 - py1;
422 }
423 return bbox;
424}
425
426////////////////////////////////////////////////////////////////////////////////
427/// Set X coordinate of the center of the BoundingBox
428
430{
431 Double_t w2 = 0.5 * (fX2 - fX1);
435}
436
437////////////////////////////////////////////////////////////////////////////////
438/// Set Y coordinate of the center of the BoundingBox
439
441{
442 Double_t h2 = 0.5 * (fY2 - fY1);
444 SetStartPoint(fX1, midy - h2);
445 SetEndPoint(fX2, midy + h2);
446}
447
448////////////////////////////////////////////////////////////////////////////////
449/// Set left hand side of BoundingBox to a value
450/// (resize in x direction on left)
451
453{
454 if (fX2 > fX1)
456 else
458}
459
460////////////////////////////////////////////////////////////////////////////////
461/// Set right hands ide of BoundingBox to a value
462/// (resize in x direction on right)
463
465{
466 if (fX2 > fX1)
468 else
470}
471
472////////////////////////////////////////////////////////////////////////////////
473/// Set top of BoundingBox to a value (resize in y direction on top)
474
476{
477 if (fY2 > fY1)
479 else
481}
482
483////////////////////////////////////////////////////////////////////////////////
484/// Set bottom of BoundingBox to a value
485/// (resize in y direction on bottom)
486
488{
489 if (fY2 > fY1)
491 else
493}
@ 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
@ kMove
Definition GuiTypes.h:375
@ kPointer
Definition GuiTypes.h:376
bool Bool_t
Boolean (0=false, 1=true) (bool)
Definition RtypesCore.h:77
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
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 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...
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
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.
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.
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 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
void SetBBoxCenterY(const Int_t y) override
Set Y coordinate of the center of the BoundingBox.
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:549
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:845
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:777
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:2385
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:657
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:673
Double_t Cos(Double_t)
Returns the cosine of an angle of x radians.
Definition TMath.h:605
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:599
Rectangle structure (maps to the X11 XRectangle structure)
Definition GuiTypes.h:362