Logo ROOT  
Reference Guide
TArrow.cxx
Go to the documentation of this file.
1// @(#)root/graf:$Id$
2// Author: Rene Brun 17/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 <iostream>
13#include "TROOT.h"
14#include "TMath.h"
15#include "TArrow.h"
16#include "TVirtualPad.h"
17#include "TVirtualPS.h"
18#include "TVirtualX.h"
19
23
25
26/** \class TArrow
27\ingroup BasicGraphics
28
29Draw all kinds of Arrows.
30
31The different arrow's formats are explained in TArrow::TArrow.
32The picture below gives some examples.
33
34Once an arrow is drawn on the screen:
35
36- One can click on one of the edges and move this edge.
37- One can click on any other arrow part to move the entire arrow.
38
39Begin_Macro(source)
40../../../tutorials/graphics/arrows.C
41End_Macro
42*/
43
44////////////////////////////////////////////////////////////////////////////////
45/// Arrow default constructor.
46
48{
50 fArrowSize = 0.;
51}
52
53////////////////////////////////////////////////////////////////////////////////
54/// Arrow normal constructor.
55///
56/// Define an arrow between points x1,y1 and x2,y2
57/// the `arrowsize` is in percentage of the pad height
58/// Opening angle between the two sides of the arrow is fAngle (60 degrees)
59/// ~~~ {.cpp}
60/// option = ">" -------->
61/// option = "|->" |------->
62/// option = "<" <--------
63/// option = "<-|" <-------|
64/// option = "->-" ---->----
65/// option = "-<-" ----<----
66/// option = "-|>-" ---|>----
67/// option = "<>" <------->
68/// option = "<|>" <|-----|> arrow defined by a triangle
69/// ~~~
70/// Note:
71///
72/// - If FillColor == 0 an open triangle is drawn, otherwise a full triangle is
73/// drawn with the fill color. The default is filled with LineColor
74/// - The "Begin" and "end" bars options can be combined with any other options.
75/// - The 9 options described above cannot be mixed.
76
78 Float_t arrowsize ,Option_t *option)
79 :TLine(x1,y1,x2,y2), TAttFill(0,1001)
80{
81
83 fArrowSize = arrowsize;
86}
87
88////////////////////////////////////////////////////////////////////////////////
89/// Arrow default destructor.
90
92{
93}
94
95////////////////////////////////////////////////////////////////////////////////
96/// Copy constructor.
97
99{
101 fArrowSize = 0.;
102 arrow.TArrow::Copy(*this);
103}
104
105////////////////////////////////////////////////////////////////////////////////
106/// Copy this arrow to arrow
107
108void TArrow::Copy(TObject &obj) const
109{
110 TLine::Copy(obj);
111 TAttFill::Copy(((TArrow&)obj));
112 ((TArrow&)obj).fAngle = fAngle;
113 ((TArrow&)obj).fArrowSize = fArrowSize;
114 ((TArrow&)obj).fOption = fOption;
115}
116
117////////////////////////////////////////////////////////////////////////////////
118/// Draw this arrow with its current attributes.
119
121{
122 Option_t *opt;
123 if (option && strlen(option)) opt = option;
124 else opt = (char*)GetOption();
125
126 AppendPad(opt);
127}
128
129////////////////////////////////////////////////////////////////////////////////
130/// Draw this arrow with new coordinates.
131///
132/// - if `arrowsize` is <= 0, `arrowsize` will be the current arrow size
133/// - if `option=""`, `option` will be the current arrow option
134
136 Float_t arrowsize ,Option_t *option)
137{
138
139 Float_t size = arrowsize;
140 if (size <= 0) size = fArrowSize;
141 if (size <= 0) size = 0.05;
142 const char* opt = option;
143 if (!opt || !opt[0]) opt = fOption.Data();
144 if (!opt || !opt[0]) opt = "|>";
145 TArrow *newarrow = new TArrow(x1,y1,x2,y2,size,opt);
146 newarrow->SetAngle(fAngle);
147 TAttLine::Copy(*newarrow);
148 TAttFill::Copy(*newarrow);
149 newarrow->SetBit(kCanDelete);
150 newarrow->AppendPad(opt);
151 return newarrow;
152}
153
154////////////////////////////////////////////////////////////////////////////////
155/// Paint this arrow with its current attributes.
156
158{
159 if (!gPad) return;
160 Option_t *opt;
161 if (option && strlen(option)) opt = option;
162 else opt = (char*)GetOption();
163 if (TestBit(kLineNDC))
164 PaintArrow(gPad->GetX1() + fX1 * (gPad->GetX2() - gPad->GetX1()),
165 gPad->GetY1() + fY1 * (gPad->GetY2() - gPad->GetY1()),
166 gPad->GetX1() + fX2 * (gPad->GetX2() - gPad->GetX1()),
167 gPad->GetY1() + fY2 * (gPad->GetY2() - gPad->GetY1()), fArrowSize, opt);
168 else
169 PaintArrow(gPad->XtoPad(fX1), gPad->YtoPad(fY1), gPad->XtoPad(fX2), gPad->YtoPad(fY2), fArrowSize, opt);
170}
171
172////////////////////////////////////////////////////////////////////////////////
173/// Draw this arrow
174
176 Float_t arrowsize, Option_t *option)
177{
178 if (!gPad) return;
179 // Compute the gPad coordinates in TRUE normalized space (NDC)
180 Int_t iw = gPad->GetWw();
181 Int_t ih = gPad->GetWh();
182 Double_t x1p,y1p,x2p,y2p;
183 gPad->GetPadPar(x1p,y1p,x2p,y2p);
184 Int_t ix1 = (Int_t)(iw*x1p);
185 Int_t iy1 = (Int_t)(ih*y1p);
186 Int_t ix2 = (Int_t)(iw*x2p);
187 Int_t iy2 = (Int_t)(ih*y2p);
188 if (ix1==ix2||iy1==iy2) return;
189
190 // Option and attributes
191 TString opt = option;
192 opt.ToLower();
195
196
197 Double_t wndc = TMath::Min(1.,(Double_t)iw/(Double_t)ih);
198 Double_t hndc = TMath::Min(1.,(Double_t)ih/(Double_t)iw);
199 Double_t rh = hndc/(Double_t)ih;
200 Double_t rw = wndc/(Double_t)iw;
201 Double_t x1ndc = (Double_t)ix1*rw;
202 Double_t y1ndc = (Double_t)iy1*rh;
203 Double_t x2ndc = (Double_t)ix2*rw;
204 Double_t y2ndc = (Double_t)iy2*rh;
205
206 // Ratios to convert user space in TRUE normalized space (NDC)
207 Double_t rx1,ry1,rx2,ry2;
208 gPad->GetRange(rx1,ry1,rx2,ry2);
209 Double_t rx = (x2ndc-x1ndc)/(rx2-rx1);
210 Double_t ry = (y2ndc-y1ndc)/(ry2-ry1);
211
212 // Arrow position and arrow's middle in NDC space
213 Double_t x1n = rx*(x1-rx1)+x1ndc;
214 Double_t x2n = rx*(x2-rx1)+x1ndc;
215 Double_t y1n = ry*(y1-ry1)+y1ndc;
216 Double_t y2n = ry*(y2-ry1)+y1ndc;
217 Double_t xm = (x1n+x2n)/2;
218 Double_t ym = (y1n+y2n)/2;
219
220 // Arrow heads size
221 Double_t length = TMath::Sqrt(Double_t((x2n-x1n)*(x2n-x1n)+(y2n-y1n)*(y2n-y1n)));
222 Double_t rSize = 0.7*arrowsize;
223 Double_t dSize = rSize*TMath::Tan(TMath::Pi()*fAngle/360);
224 Double_t cosT = (length > 0) ? (x2n-x1n)/length : 1.;
225 Double_t sinT = (length > 0) ? (y2n-y1n)/length : 0.;
226
227 // Draw the start and end bars if needed
228 if (opt.BeginsWith("|-")) {
229 Double_t x1ar[2], y1ar[2];
230 x1ar[0] = x1n-sinT*dSize;
231 y1ar[0] = y1n+cosT*dSize;
232 x1ar[1] = x1n+sinT*dSize;
233 y1ar[1] = y1n-cosT*dSize;
234 // NDC to user coordinates
235 for (Int_t i=0; i<2; i++) {
236 x1ar[i] = (1/rx)*(x1ar[i]-x1ndc)+rx1;
237 y1ar[i] = (1/ry)*(y1ar[i]-y1ndc)+ry1;
238 }
239 gPad->PaintLine(x1ar[0],y1ar[0],x1ar[1],y1ar[1]);
240 opt(0) = ' ';
241 }
242 if (opt.EndsWith("-|")) {
243 Double_t x2ar[2], y2ar[2];
244 x2ar[0] = x2n-sinT*dSize;
245 y2ar[0] = y2n+cosT*dSize;
246 x2ar[1] = x2n+sinT*dSize;
247 y2ar[1] = y2n-cosT*dSize;
248 // NDC to user coordinates
249 for (Int_t i=0; i<2; i++) {
250 x2ar[i] = (1/rx)*(x2ar[i]-x1ndc)+rx1;
251 y2ar[i] = (1/ry)*(y2ar[i]-y1ndc)+ry1;
252 }
253 gPad->PaintLine(x2ar[0],y2ar[0],x2ar[1],y2ar[1]);
254 opt(opt.Length()-1) = ' ';
255 }
256
257 // Move arrow head's position if needed
258 Double_t x1h = x1n;
259 Double_t y1h = y1n;
260 Double_t x2h = x2n;
261 Double_t y2h = y2n;
262 if (opt.Contains("->-") || opt.Contains("-|>-")) {
263 x2h = xm + cosT*rSize/2;
264 y2h = ym + sinT*rSize/2;
265 }
266 if (opt.Contains("-<-") || opt.Contains("-<|-")) {
267 x1h = xm - cosT*rSize/2;
268 y1h = ym - sinT*rSize/2;
269 }
270
271 // Paint Arrow body
272 if (opt.Contains("|>") && !opt.Contains("-|>-")) {
273 x2n -= cosT*rSize;
274 y2n -= sinT*rSize;
275 }
276 if (opt.Contains("<|") && !opt.Contains("-<|-")) {
277 x1n += cosT*rSize;
278 y1n += sinT*rSize;
279 }
280 x1n = (1/rx)*(x1n-x1ndc)+rx1;
281 y1n = (1/ry)*(y1n-y1ndc)+ry1;
282 x2n = (1/rx)*(x2n-x1ndc)+rx1;
283 y2n = (1/ry)*(y2n-y1ndc)+ry1;
284 gPad->PaintLine(x1n,y1n,x2n,y2n);
285
286 // Draw the arrow's head(s)
287 if (opt.Contains(">")) {
288 Double_t x2ar[4], y2ar[4];
289
290 x2ar[0] = x2h - rSize*cosT - sinT*dSize;
291 y2ar[0] = y2h - rSize*sinT + cosT*dSize;
292 x2ar[1] = x2h;
293 y2ar[1] = y2h;
294 x2ar[2] = x2h - rSize*cosT + sinT*dSize;
295 y2ar[2] = y2h - rSize*sinT - cosT*dSize;
296 x2ar[3] = x2ar[0];
297 y2ar[3] = y2ar[0];
298
299 // NDC to user coordinates
300 for (Int_t i=0; i<4; i++) {
301 x2ar[i] = (1/rx)*(x2ar[i]-x1ndc)+rx1;
302 y2ar[i] = (1/ry)*(y2ar[i]-y1ndc)+ry1;
303 }
304 if (opt.Contains("|>")) {
305 if (gVirtualX) gVirtualX->SetLineStyle(1);
307 if (GetFillColor()) {
308 gPad->PaintFillArea(3,x2ar,y2ar);
309 gPad->PaintPolyLine(4,x2ar,y2ar);
310 } else {
311 gPad->PaintPolyLine(4,x2ar,y2ar);
312 }
313 } else {
314 gPad->PaintPolyLine(3,x2ar,y2ar);
315 }
316 }
317
318 if (opt.Contains("<")) {
319 Double_t x1ar[4], y1ar[4];
320 x1ar[0] = x1h + rSize*cosT + sinT*dSize;
321 y1ar[0] = y1h + rSize*sinT - cosT*dSize;
322 x1ar[1] = x1h;
323 y1ar[1] = y1h;
324 x1ar[2] = x1h + rSize*cosT - sinT*dSize;
325 y1ar[2] = y1h + rSize*sinT + cosT*dSize;
326 x1ar[3] = x1ar[0];
327 y1ar[3] = y1ar[0];
328
329 // NDC to user coordinates
330 for (Int_t i=0; i<4; i++) {
331 x1ar[i] = (1/rx)*(x1ar[i]-x1ndc)+rx1;
332 y1ar[i] = (1/ry)*(y1ar[i]-y1ndc)+ry1;
333 }
334 if (opt.Contains("<|")) {
335 if (gVirtualX) gVirtualX->SetLineStyle(1);
337 if (GetFillColor()) {
338 gPad->PaintFillArea(3,x1ar,y1ar);
339 gPad->PaintPolyLine(4,x1ar,y1ar);
340 } else {
341 gPad->PaintPolyLine(4,x1ar,y1ar);
342 }
343 } else {
344 gPad->PaintPolyLine(3,x1ar,y1ar);
345 }
346 }
347}
348
349////////////////////////////////////////////////////////////////////////////////
350/// Save primitive as a C++ statement(s) on output stream out
351
352void TArrow::SavePrimitive(std::ostream &out, Option_t * /*= ""*/)
353{
354
355 char quote = '"';
356 if (gROOT->ClassSaved(TArrow::Class())) {
357 out<<" ";
358 } else {
359 out<<" TArrow *";
360 }
361 out<<"arrow = new TArrow("<<fX1<<","<<fY1<<","<<fX2<<","<<fY2
362 <<","<<fArrowSize<<","<<quote<<GetDrawOption()<<quote<<");"<<std::endl;
363
364 SaveFillAttributes(out,"arrow",0,1);
365 SaveLineAttributes(out,"arrow",1,1,1);
366
367 if (TestBit(kLineNDC))
368 out<<" arrow->SetNDC();"<<std::endl;
369
370 if (fAngle!=60)
371 out << " arrow->SetAngle(" << GetAngle() << ");" << std::endl;
372
373 out<<" arrow->Draw();"<<std::endl;
374}
375
376
377////////////////////////////////////////////////////////////////////////////////
378/// Set default angle.
379
381{
383}
384
385
386////////////////////////////////////////////////////////////////////////////////
387/// Set default arrow sive.
388
390{
391 fgDefaultArrowSize = ArrowSize;
392}
393
394
395////////////////////////////////////////////////////////////////////////////////
396/// Set default option.
397
399{
400
401 fgDefaultOption = Option;
402}
403
404
405////////////////////////////////////////////////////////////////////////////////
406/// Get default angle.
407
409{
410
411 return fgDefaultAngle;
412}
413
414
415////////////////////////////////////////////////////////////////////////////////
416/// Get default arrow size.
417
419{
420
421 return fgDefaultArrowSize;
422}
423
424
425////////////////////////////////////////////////////////////////////////////////
426/// Get default option.
427
429{
430
431 return fgDefaultOption.Data();
432}
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
int Int_t
Definition: RtypesCore.h:45
float Float_t
Definition: RtypesCore.h:57
double Double_t
Definition: RtypesCore.h:59
const char Option_t
Definition: RtypesCore.h:66
#define ClassImp(name)
Definition: Rtypes.h:375
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 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 x2
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint TPoint const char y2
Option_t Option_t TPoint TPoint const char y1
#define gROOT
Definition: TROOT.h:404
R__EXTERN TVirtualPS * gVirtualPS
Definition: TVirtualPS.h:81
#define gPad
Definition: TVirtualPad.h:288
#define gVirtualX
Definition: TVirtualX.h:338
Draw all kinds of Arrows.
Definition: TArrow.h:29
Float_t GetAngle() const
Definition: TArrow.h:51
Option_t * GetOption() const override
Definition: TArrow.h:53
static Float_t GetDefaultAngle()
Get default angle.
Definition: TArrow.cxx:408
Float_t fArrowSize
Arrow Size.
Definition: TArrow.h:32
static void SetDefaultOption(Option_t *Option)
Set default option.
Definition: TArrow.cxx:398
static TClass * Class()
static void SetDefaultArrowSize(Float_t ArrowSize)
Set default arrow sive.
Definition: TArrow.cxx:389
static void SetDefaultAngle(Float_t Angle)
Set default angle.
Definition: TArrow.cxx:380
static Float_t fgDefaultAngle
Default Arrow opening angle (degrees)
Definition: TArrow.h:35
static Option_t * GetDefaultOption()
Get default option.
Definition: TArrow.cxx:428
static Float_t fgDefaultArrowSize
Default Arrow Size.
Definition: TArrow.h:36
virtual TArrow * DrawArrow(Double_t x1, Double_t y1, Double_t x2, Double_t y2, Float_t arrowsize=0, Option_t *option="")
Draw this arrow with new coordinates.
Definition: TArrow.cxx:135
void Paint(Option_t *option="") override
Paint this arrow with its current attributes.
Definition: TArrow.cxx:157
TArrow()
Arrow default constructor.
Definition: TArrow.cxx:47
virtual ~TArrow()
Arrow default destructor.
Definition: TArrow.cxx:91
Float_t fAngle
Arrow opening angle (degrees)
Definition: TArrow.h:31
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save primitive as a C++ statement(s) on output stream out.
Definition: TArrow.cxx:352
static TString fgDefaultOption
Default Arrow shapes.
Definition: TArrow.h:37
TString fOption
Arrow shapes.
Definition: TArrow.h:33
void Draw(Option_t *option="") override
Draw this arrow with its current attributes.
Definition: TArrow.cxx:120
virtual void PaintArrow(Double_t x1, Double_t y1, Double_t x2, Double_t y2, Float_t arrowsize=0.05, Option_t *option=">")
Draw this arrow.
Definition: TArrow.cxx:175
virtual void SetAngle(Float_t angle=60)
Definition: TArrow.h:58
static Float_t GetDefaultArrowSize()
Get default arrow size.
Definition: TArrow.cxx:418
void Copy(TObject &arrow) const override
Copy this arrow to arrow.
Definition: TArrow.cxx:108
Fill Area Attributes class.
Definition: TAttFill.h:19
virtual Color_t GetFillColor() const
Return the fill area color.
Definition: TAttFill.h:30
void Copy(TAttFill &attfill) const
Copy this fill attributes to a new TAttFill.
Definition: TAttFill.cxx:204
virtual void Modify()
Change current fill area attributes if necessary.
Definition: TAttFill.cxx:213
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition: TAttFill.h:37
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:236
virtual Color_t GetLineColor() const
Return the line color.
Definition: TAttLine.h:33
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition: TAttLine.h:42
virtual void Modify()
Change current line attributes if necessary.
Definition: TAttLine.cxx:245
void Copy(TAttLine &attline) const
Copy this line attributes to a new TAttLine.
Definition: TAttLine.cxx:175
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:273
Use the TLine constructor to create a simple line.
Definition: TLine.h:22
Double_t fY1
Y of 1st point.
Definition: TLine.h:26
Double_t fX1
X of 1st point.
Definition: TLine.h:25
void Copy(TObject &line) const override
Copy this line to line.
Definition: TLine.cxx:76
Double_t fX2
X of 2nd point.
Definition: TLine.h:27
@ kLineNDC
Use NDC coordinates.
Definition: TLine.h:33
Double_t fY2
Y of 2nd point.
Definition: TLine.h:28
Mother of all ROOT objects.
Definition: TObject.h:37
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:187
virtual Option_t * GetDrawOption() const
Get option used by the graphics system to draw this object.
Definition: TObject.cxx:347
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition: TObject.cxx:107
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:698
@ kCanDelete
if object in a list can be deleted
Definition: TObject.h:58
Basic string class.
Definition: TString.h:136
Ssiz_t Length() const
Definition: TString.h:410
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1155
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2207
const char * Data() const
Definition: TString.h:369
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:615
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:624
double Angle(const Vector1 &v1, const Vector2 &v2)
Find Angle between two vectors.
Definition: VectorUtil.h:169
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition: TMath.h:660
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition: TMathBase.h:198
constexpr Double_t Pi()
Definition: TMath.h:37
Double_t Tan(Double_t)
Returns the tangent of an angle of x radians.
Definition: TMath.h:598