Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TCurlyArc.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 TCurlyArc
13\ingroup BasicGraphics
14
15Implements curly or wavy arcs 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 TCurlyLine 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 <iostream>
29#include "TCurlyArc.h"
30#include "TROOT.h"
31#include "TVirtualPad.h"
32#include "TBoxInteractive.h"
33#include "TAttMarker.h"
34#include "TMath.h"
35#include "TPoint.h"
36
40
41
42////////////////////////////////////////////////////////////////////////////////
43/// Default constructor
44
46{
47 fR1 = 0.;
48 fPhimin = 0.;
49 fPhimax = 0.;
50 fTheta = 0.;
51}
52
53////////////////////////////////////////////////////////////////////////////////
54/// Create a new TCurlyArc with center (x1, y1) and radius rad.
55/// The wavelength and amplitude are given in percent of the line length
56/// phimin and phimax are given in degrees.
57
59 Double_t rad, Double_t phimin, Double_t phimax,
60 Double_t wl, Double_t amp)
61 : fR1(rad), fPhimin(phimin),fPhimax(phimax)
62{
63 fX1 = x1;
64 fY1 = y1;
66 fAmplitude = amp;
67 fWaveLength = wl;
68 fTheta = 0;
69 Build();
70}
71
72////////////////////////////////////////////////////////////////////////////////
73/// Create a curly (Gluon) or wavy (Gamma) arc.
74
76{
77 Double_t pixeltoX = 1;
78 Double_t pixeltoY = 1;
79 Double_t rPix = fR1;
80 if (gPad) {
81 Double_t pxrange = gPad->GetPadWidth();
82 Double_t pyrange = -1. * gPad->GetPadHeight();
83 Double_t xrange = gPad->GetX2() - gPad->GetX1();
84 Double_t yrange = gPad->GetY2() - gPad->GetY1();
85 pixeltoX = xrange / pxrange;
86 pixeltoY = yrange/pyrange;
87 rPix = fR1 / pixeltoX;
88 }
89 Double_t dang = fPhimax - fPhimin;
90 if (dang < 0) dang += 360;
91 Double_t length = TMath::Pi() * fR1 * dang/180;
92 Double_t x1sav = fX1;
93 Double_t y1sav = fY1;
94 fX1 = fY1 = 0;
95 fX2 = length;
96 fY2 = 0;
98 fX1 = x1sav;
99 fY1 = y1sav;
100 Double_t *xv= GetX();
101 Double_t *yv= GetY();
102 Double_t xx, yy, angle;
103 for(Int_t i = 0; i < fNsteps; i++){
104 angle = xv[i] / rPix + fPhimin * TMath::Pi()/180;
105 xx = (yv[i] + rPix) * cos(angle);
106 yy = (yv[i] + rPix) * sin(angle);
107 xx *= pixeltoX;
108 yy *= TMath::Abs(pixeltoY);
109 xv[i] = xx + fX1;
110 yv[i] = yy + fY1;
111 }
112 if (gPad)
113 gPad->Modified();
114}
115
116////////////////////////////////////////////////////////////////////////////////
117/// Compute distance from point px,py to an arc.
118///
119/// Compute the closest distance of approach from point px,py to this arc.
120/// The distance is computed in pixels units.
121
123{
124 if (!gPad) return 9999;
125 // Compute distance of point to center of arc
126 Int_t pxc = gPad->XtoAbsPixel(gPad->XtoPad(fX1));
127 Int_t pyc = gPad->YtoAbsPixel(gPad->YtoPad(fY1));
128 Double_t dist = TMath::Sqrt(Long64_t(pxc-px)*(pxc-px)+Long64_t(pyc-py)*(pyc-py));
129 Double_t cosa = (px - pxc)/dist;
130 Double_t sina = (pyc - py)/dist;
131 Double_t phi = TMath::ATan2(sina,cosa);
132 if (phi < 0) phi += 2 * TMath::Pi();
133 phi = phi * 180 / TMath::Pi();
134 if (fPhimax > fPhimin){
135 if (phi < fPhimin || phi > fPhimax) return 9999;
136 } else {
137 if (phi > fPhimin && phi < fPhimax) return 9999;
138 }
139 Int_t pxa = gPad->XtoAbsPixel(gPad->XtoPad(fX1 + cosa*fR1));
140 Int_t pya = gPad->YtoAbsPixel(gPad->YtoPad(fY1 + sina*fR1));
141 Double_t dista = TMath::Sqrt(Long64_t(pxc-pxa)*(pxc-pxa)+Long64_t(pyc-pya)*(pyc-pya));
142 return (Int_t) TMath::Abs(dist - dista);
143}
144
146 public:
148 TBoxInteractive(kFALSE, c->GetStartX() - c->GetRadius(), c->GetStartY() - c->GetRadius(), c->GetStartX() + c->GetRadius(), c->GetStartY() + c->GetRadius())
149 {
150 }
151
152 void PaintOutline(TVirtualPad &parent) override
153 {
154 auto c = static_cast<TCurlyArc *> (GetObject());
155
156 int np = 10;
157 std::vector<Double_t> x(np+3), y(np+3);
158
159 Double_t dphi = (c->GetPhimax() - c->GetPhimin()) / 180. * TMath::Pi();
160 Double_t midx = (newX1 + newX2) / 2;
161 Double_t midy = (newY1 + newY2) / 2;
162 Double_t radius = (newX2 - newX1 + newY2 - newY1) / 4;
163
164 if (dphi < 0)
165 dphi += 2 * TMath::Pi();
166 Double_t phi0 = c->GetPhimin() / 180. * TMath::Pi();
167 for (int i = 0; i <= np; i++) {
168 Double_t angle = phi0 + i*dphi/np;
169 x[i] = parent.XtoPad(midx + radius*TMath::Cos(angle));
170 y[i] = parent.YtoPad(midy + radius*TMath::Sin(angle));
171 }
172 Bool_t full_circle = kTRUE;
173 if (c->GetPhimax() - c->GetPhimin() < 360) {
174 ++np;
175 x[np] = parent.XtoPad(midx);
176 y[np] = parent.YtoPad(midy);
177 full_circle = kFALSE;
178 }
179 ++np;
180 x[np] = x[0];
181 y[np] = y[0];
182
183 c->TAttLine::ModifyOn(parent);
184 // "i" is interactive painting
185 parent.PaintPolyLine(np+1, x.data(), y.data(), "icurlyarc");
186
187 if (!full_circle)
188 PaintDiamondCorners(parent, "icurlyarc");
189 }
190
191 void Apply(TCurlyArc *c, Bool_t usenew = kTRUE)
192 {
193 c->SetCenter(usenew ? (newX1 + newX2) / 2 : (oldX1 + oldX2) / 2,
194 usenew ? (newY1 + newY2) / 2 : (oldY1 + oldY2) / 2);
195 c->SetRadius(usenew ? (newX2 - newX1 + newY2 - newY1) / 4 : (oldX2 - oldX1 + oldY2 - oldY1) / 4);
196 }
197};
198
199////////////////////////////////////////////////////////////////////////////////
200/// Execute action corresponding to one event.
201///
202/// This member function is called when a TCurlyArc is clicked with the locator
203///
204/// If Left button clicked on one of the line end points, this point
205/// follows the cursor until button is released.
206///
207/// if Middle button clicked, the line is moved parallel to itself
208/// until the button is released.
209
211{
212 if (!gPad || !gPad->IsEditable()) return;
213
214 auto &parent = *gPad;
215
216 auto inter = parent.GetInteractive<TCurlyArcInteractive>(this);
217
218 switch (event) {
219
220 case kArrowKeyPress:
221 case kButton1Down:
222 inter = parent.MakeInteractive<TCurlyArcInteractive>(this, this);
223
224 // No break !!!
225 case kMouseMotion: {
226 TCurlyArcInteractive dummy(this);
227 if (!inter) inter = &dummy;
228 inter->CalcPixelCoord(parent, dummy.oldX1, dummy.oldY1, dummy.oldX2, dummy.oldY2);
229
230 if (!inter->SelectDiamondCorner(px, py, kFALSE))
231 parent.FreeInteractive(this); // refuse interactive changes
232 else
233 inter->SetCursor(parent, event == kButton1Down);
234 break;
235 }
236
237 case kArrowKeyRelease:
238 case kButton1Motion:
239 if (!inter)
240 return;
241
242 if (!inter->ProcessMouseMove(parent, px, py))
243 return;
244
245 inter->ApplyChanges(parent);
246
247 if (inter->IsOpaque(parent)) {
248 inter->Apply(this);
249 parent.ShowGuidelines(this, event, inter->GetGuideChar(), true);
250 parent.Modified(kTRUE);
251 }
252
253 break;
254
255 case kButton1Up:
256 if (inter && inter->IsOpaque(parent))
257 parent.ShowGuidelines(this, event);
258
259 if (gROOT->IsEscaped()) {
260 gROOT->SetEscape(kFALSE);
261 if (inter && inter->IsOpaque(parent)) {
262 inter->Apply(this, kFALSE);
263 }
264 } else if (inter && !inter->IsOpaque(parent)) {
265 inter->Apply(this);
266 }
267
268 parent.Modified();
269 parent.FreeInteractive(this);
270 break;
271 }
272}
273
274////////////////////////////////////////////////////////////////////////////////
275/// Save primitive as a C++ statement(s) on output stream out
276
277void TCurlyArc::SavePrimitive(std::ostream &out, Option_t *option)
278{
280 out, Class(), "curlyarc",
281 TString::Format("%g, %g, %g, %g, %g, %g, %g", fX1, fY1, fR1, fPhimin, fPhimax, fWaveLength, fAmplitude));
282
283 SaveLineAttributes(out, "curlyarc", 1, 1, 1);
284 if (!fIsCurly)
285 out << " curlyarc->SetWavy();\n";
286
287 SavePrimitiveDraw(out, "curlyarc", option);
288}
289
290////////////////////////////////////////////////////////////////////////////////
291/// Set Curly Arc center.
292
294{
295 fX1 = x;
296 fY1 = y;
297 Build();
298}
299
300////////////////////////////////////////////////////////////////////////////////
301/// Set Curly Arc radius.
302
304{
305 fR1 = x;
306 Build();
307}
308
309////////////////////////////////////////////////////////////////////////////////
310/// Set Curly Arc minimum Phi.
311
313{
314 fPhimin = x;
315 Build();
316}
317
318////////////////////////////////////////////////////////////////////////////////
319/// Set Curly Arc maximum Phi.
320
322{
323 fPhimax = x;
324 Build();
325}
326
327////////////////////////////////////////////////////////////////////////////////
328/// Set default wave length.
329
331{
332 fgDefaultWaveLength = WaveLength;
333}
334
335////////////////////////////////////////////////////////////////////////////////
336/// Set default wave amplitude.
337
339{
340 fgDefaultAmplitude = Amplitude ;
341}
342
343////////////////////////////////////////////////////////////////////////////////
344/// Set default "IsCurly".
345
347{
348 fgDefaultIsCurly = IsCurly;
349}
350
351////////////////////////////////////////////////////////////////////////////////
352/// Get default wave length.
353
358
359////////////////////////////////////////////////////////////////////////////////
360/// Get default wave amplitude.
361
366
367////////////////////////////////////////////////////////////////////////////////
368/// Get default "IsCurly".
369
374
375////////////////////////////////////////////////////////////////////////////////
376/// Return the bounding Box of the Line
377
379{
380 Rectangle_t bbox{0, 0, 0, 0};
381 if (gPad) {
382 Double_t R2 = fR1 * TMath::Abs(gPad->GetY2() - gPad->GetY1()) / TMath::Abs(gPad->GetX2() - gPad->GetX1());
383 bbox.fX = gPad->XtoPixel(fX1 - fR1);
384 bbox.fY = gPad->YtoPixel(fY1 + R2);
385 bbox.fWidth = gPad->XtoPixel(fX1 + fR1) - bbox.fX;
386 bbox.fHeight = gPad->YtoPixel(fY1 - R2) - bbox.fY;
387 }
388 return bbox;
389}
390
391////////////////////////////////////////////////////////////////////////////////
392/// Return the center of the BoundingBox as TPoint in pixels
393
395{
396 TPoint p(0,0);
397 if (gPad) {
398 p.SetX(gPad->XtoPixel(fX1));
399 p.SetY(gPad->YtoPixel(fY1));
400 }
401 return p;
402}
403
404////////////////////////////////////////////////////////////////////////////////
405/// Set X coordinate of the center of the BoundingBox
406
408{
409 fX1 = GetXCoord(x);
410 Build();
411}
412
413////////////////////////////////////////////////////////////////////////////////
414/// Set Y coordinate of the center of the BoundingBox
415
417{
418 fY1 = GetYCoord(y);
419 Build();
420}
421
422////////////////////////////////////////////////////////////////////////////////
423/// Set left hand side of BoundingBox to a value
424/// (resize in x direction on left)
425
427{
428 fR1 = fX1 - GetXCoord(x);
429}
430
431////////////////////////////////////////////////////////////////////////////////
432/// Set right hand side of BoundingBox to a value
433/// (resize in x direction on right)
434
436{
437 fR1 = GetXCoord(x) - fX1;
438}
439
440////////////////////////////////////////////////////////////////////////////////
441/// Set top of BoundingBox to a value (resize in y direction on top)
442
444{
445 fR1 = GetYCoord(y) - fY1;
446}
447
448////////////////////////////////////////////////////////////////////////////////
449/// Set bottom of BoundingBox to a value
450/// (resize in y direction on bottom)
451
453{
454 fR1 = fY1 - GetYCoord(y);
455}
@ 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
#define c(i)
Definition RSha256.hxx:101
cudaEvent_t event
bool Bool_t
Boolean (0=false, 1=true) (bool)
Definition RtypesCore.h:78
constexpr Bool_t kFALSE
Definition RtypesCore.h:109
double Double_t
Double 8 bytes.
Definition RtypesCore.h:74
long long Long64_t
Portable signed long integer 8 bytes.
Definition RtypesCore.h:84
constexpr Bool_t kTRUE
Definition RtypesCore.h:108
const char Option_t
Option string (const char)
Definition RtypesCore.h:81
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t np
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint TPoint angle
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 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 CalcPixelCoord(const TVirtualPad &parent, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Calculate pixel coordinates.
void PaintDiamondCorners(TVirtualPad &parent, const char *id="idiamond")
Paint diamond corners outline.
void Apply(TCurlyArc *c, Bool_t usenew=kTRUE)
void PaintOutline(TVirtualPad &parent) override
Paint object outline.
TCurlyArcInteractive(TCurlyArc *c)
Implements curly or wavy arcs used to draw Feynman diagrams.
Definition TCurlyArc.h:16
Rectangle_t GetBBox() override
Return the bounding Box of the Line.
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
Compute distance from point px,py to an arc.
void SetBBoxX1(const Int_t x) override
Set left hand side of BoundingBox to a value (resize in x direction on left)
virtual void SetRadius(Double_t radius)
Set Curly Arc radius.
static Bool_t GetDefaultIsCurly()
Get default "IsCurly".
void Build() override
Create a curly (Gluon) or wavy (Gamma) arc.
Definition TCurlyArc.cxx:75
virtual void SetPhimin(Double_t phimin)
Set Curly Arc minimum Phi.
Double_t fTheta
used internally
Definition TCurlyArc.h:22
static Double_t GetDefaultWaveLength()
Get default wave length.
static TClass * Class()
virtual void SetCenter(Double_t x1, Double_t y1)
Set Curly Arc center.
Double_t fPhimax
end phi (degrees)
Definition TCurlyArc.h:21
void SetBBoxY2(const Int_t y) override
Set bottom of BoundingBox to a value (resize in y direction on bottom)
void SetBBoxX2(const Int_t x) override
Set right hand side of BoundingBox to a value (resize in x direction on right)
TCurlyArc()
Default constructor.
Definition TCurlyArc.cxx:45
static Double_t fgDefaultWaveLength
default wavelength
Definition TCurlyArc.h:24
static void SetDefaultWaveLength(Double_t WaveLength)
Set default wave length.
static void SetDefaultAmplitude(Double_t Amplitude)
Set default wave amplitude.
Double_t fPhimin
start phi (degrees)
Definition TCurlyArc.h:20
Double_t fR1
Radius of arc.
Definition TCurlyArc.h:19
static Double_t fgDefaultAmplitude
default amplitude
Definition TCurlyArc.h:25
static Double_t GetDefaultAmplitude()
Get default wave amplitude.
static void SetDefaultIsCurly(Bool_t IsCurly)
Set default "IsCurly".
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
Execute action corresponding to one event.
TPoint GetBBoxCenter() override
Return the center of the BoundingBox as TPoint in pixels.
static Bool_t fgDefaultIsCurly
default curly type
Definition TCurlyArc.h:26
void SavePrimitive(std::ostream &out, Option_t *="") override
Save primitive as a C++ statement(s) on output stream out.
void SetBBoxCenterY(const Int_t y) override
Set Y coordinate of the center of the BoundingBox.
void SetBBoxY1(const Int_t y) override
Set top of BoundingBox to a value (resize in y direction on top)
virtual void SetPhimax(Double_t phimax)
Set Curly Arc maximum Phi.
void SetBBoxCenterX(const Int_t x) override
Set X coordinate of the center of the BoundingBox.
Double_t fY1
start y, center for arc
Definition TCurlyLine.h:23
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
Int_t fNsteps
used internally (controls precision)
Definition TCurlyLine.h:28
virtual void Build()
Create a curly (Gluon) or wavy (Gamma) line.
Double_t fY2
end y
Definition TCurlyLine.h:25
Double_t fX1
start x, center for arc
Definition TCurlyLine.h:22
Double_t fX2
end x
Definition TCurlyLine.h:24
Bool_t fIsCurly
true: Gluon, false: Gamma
Definition TCurlyLine.h:29
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
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
TObject * GetObject() const
Definition TVirtualPad.h:79
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition TVirtualPad.h:53
virtual Double_t YtoPad(Double_t y) const =0
virtual void PaintPolyLine(Int_t n, Float_t *x, Float_t *y, Option_t *option="")=0
virtual Double_t XtoPad(Double_t x) const =0
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
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
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:122
Rectangle structure (maps to the X11 XRectangle structure)
Definition GuiTypes.h:362