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 
29 Draw all kinds of Arrows.
30 
31 The different arrow's formats are explained in TArrow::TArrow.
32 The picture below gives some examples.
33 
34 Once 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 
39 Begin_Macro(source)
40 ../../../tutorials/graphics/arrows.C
41 End_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;
84  fOption = option;
86 }
87 
88 ////////////////////////////////////////////////////////////////////////////////
89 /// Arrow default destructor.
90 
92 {
93 }
94 
95 ////////////////////////////////////////////////////////////////////////////////
96 /// Copy constructor.
97 
99 {
101  fArrowSize = 0.;
102  arrow.Copy(*this);
103 }
104 
105 ////////////////////////////////////////////////////////////////////////////////
106 /// Copy this arrow to arrow
107 
108 void 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 
120 void TArrow::Draw(Option_t *option)
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 }
152 
153 ////////////////////////////////////////////////////////////////////////////////
154 /// Paint this arrow with its current attributes.
155 
156 void TArrow::Paint(Option_t *option)
157 {
158  if (!gPad) return;
159  Option_t *opt;
160  if (option && strlen(option)) opt = option;
161  else opt = (char*)GetOption();
162  if (TestBit(kLineNDC))
163  PaintArrow(gPad->GetX1() + fX1 * (gPad->GetX2() - gPad->GetX1()),
164  gPad->GetY1() + fY1 * (gPad->GetY2() - gPad->GetY1()),
165  gPad->GetX1() + fX2 * (gPad->GetX2() - gPad->GetX1()),
166  gPad->GetY1() + fY2 * (gPad->GetY2() - gPad->GetY1()), fArrowSize, opt);
167  else
168  PaintArrow(gPad->XtoPad(fX1), gPad->YtoPad(fY1), gPad->XtoPad(fX2), gPad->YtoPad(fY2), fArrowSize, opt);
169 }
170 
171 ////////////////////////////////////////////////////////////////////////////////
172 /// Draw this arrow
173 
175  Float_t arrowsize, Option_t *option)
176 {
177  if (!gPad) return;
178  // Compute the gPad coordinates in TRUE normalized space (NDC)
179  Int_t iw = gPad->GetWw();
180  Int_t ih = gPad->GetWh();
181  Double_t x1p,y1p,x2p,y2p;
182  gPad->GetPadPar(x1p,y1p,x2p,y2p);
183  Int_t ix1 = (Int_t)(iw*x1p);
184  Int_t iy1 = (Int_t)(ih*y1p);
185  Int_t ix2 = (Int_t)(iw*x2p);
186  Int_t iy2 = (Int_t)(ih*y2p);
187  if (ix1==ix2||iy1==iy2) return;
188 
189  // Option and attributes
190  TString opt = option;
191  opt.ToLower();
194 
195 
196  Double_t wndc = TMath::Min(1.,(Double_t)iw/(Double_t)ih);
197  Double_t hndc = TMath::Min(1.,(Double_t)ih/(Double_t)iw);
198  Double_t rh = hndc/(Double_t)ih;
199  Double_t rw = wndc/(Double_t)iw;
200  Double_t x1ndc = (Double_t)ix1*rw;
201  Double_t y1ndc = (Double_t)iy1*rh;
202  Double_t x2ndc = (Double_t)ix2*rw;
203  Double_t y2ndc = (Double_t)iy2*rh;
204 
205  // Ratios to convert user space in TRUE normalized space (NDC)
206  Double_t rx1,ry1,rx2,ry2;
207  gPad->GetRange(rx1,ry1,rx2,ry2);
208  Double_t rx = (x2ndc-x1ndc)/(rx2-rx1);
209  Double_t ry = (y2ndc-y1ndc)/(ry2-ry1);
210 
211  // Arrow position and arrow's middle in NDC space
212  Double_t x1n = rx*(x1-rx1)+x1ndc;
213  Double_t x2n = rx*(x2-rx1)+x1ndc;
214  Double_t y1n = ry*(y1-ry1)+y1ndc;
215  Double_t y2n = ry*(y2-ry1)+y1ndc;
216  Double_t xm = (x1n+x2n)/2;
217  Double_t ym = (y1n+y2n)/2;
218 
219  // Arrow heads size
220  Double_t length = TMath::Sqrt(Double_t((x2n-x1n)*(x2n-x1n)+(y2n-y1n)*(y2n-y1n)));
221  Double_t rSize = 0.7*arrowsize;
222  Double_t dSize = rSize*TMath::Tan(TMath::Pi()*fAngle/360);
223  Double_t cosT = (length > 0) ? (x2n-x1n)/length : 1.;
224  Double_t sinT = (length > 0) ? (y2n-y1n)/length : 0.;
225 
226  // Draw the start and end bars if needed
227  if (opt.BeginsWith("|-")) {
228  Double_t x1ar[2], y1ar[2];
229  x1ar[0] = x1n-sinT*dSize;
230  y1ar[0] = y1n+cosT*dSize;
231  x1ar[1] = x1n+sinT*dSize;
232  y1ar[1] = y1n-cosT*dSize;
233  // NDC to user coordinates
234  for (Int_t i=0; i<2; i++) {
235  x1ar[i] = (1/rx)*(x1ar[i]-x1ndc)+rx1;
236  y1ar[i] = (1/ry)*(y1ar[i]-y1ndc)+ry1;
237  }
238  gPad->PaintLine(x1ar[0],y1ar[0],x1ar[1],y1ar[1]);
239  opt(0) = ' ';
240  }
241  if (opt.EndsWith("-|")) {
242  Double_t x2ar[2], y2ar[2];
243  x2ar[0] = x2n-sinT*dSize;
244  y2ar[0] = y2n+cosT*dSize;
245  x2ar[1] = x2n+sinT*dSize;
246  y2ar[1] = y2n-cosT*dSize;
247  // NDC to user coordinates
248  for (Int_t i=0; i<2; i++) {
249  x2ar[i] = (1/rx)*(x2ar[i]-x1ndc)+rx1;
250  y2ar[i] = (1/ry)*(y2ar[i]-y1ndc)+ry1;
251  }
252  gPad->PaintLine(x2ar[0],y2ar[0],x2ar[1],y2ar[1]);
253  opt(opt.Length()-1) = ' ';
254  }
255 
256  // Move arrow head's position if needed
257  Double_t x1h = x1n;
258  Double_t y1h = y1n;
259  Double_t x2h = x2n;
260  Double_t y2h = y2n;
261  if (opt.Contains("->-") || opt.Contains("-|>-")) {
262  x2h = xm + cosT*rSize/2;
263  y2h = ym + sinT*rSize/2;
264  }
265  if (opt.Contains("-<-") || opt.Contains("-<|-")) {
266  x1h = xm - cosT*rSize/2;
267  y1h = ym - sinT*rSize/2;
268  }
269 
270  // Paint Arrow body
271  if (opt.Contains("|>") && !opt.Contains("-|>-")) {
272  x2n -= cosT*rSize;
273  y2n -= sinT*rSize;
274  }
275  if (opt.Contains("<|") && !opt.Contains("-<|-")) {
276  x1n += cosT*rSize;
277  y1n += sinT*rSize;
278  }
279  x1n = (1/rx)*(x1n-x1ndc)+rx1;
280  y1n = (1/ry)*(y1n-y1ndc)+ry1;
281  x2n = (1/rx)*(x2n-x1ndc)+rx1;
282  y2n = (1/ry)*(y2n-y1ndc)+ry1;
283  gPad->PaintLine(x1n,y1n,x2n,y2n);
284 
285  // Draw the arrow's head(s)
286  if (opt.Contains(">")) {
287  Double_t x2ar[4], y2ar[4];
288 
289  x2ar[0] = x2h - rSize*cosT - sinT*dSize;
290  y2ar[0] = y2h - rSize*sinT + cosT*dSize;
291  x2ar[1] = x2h;
292  y2ar[1] = y2h;
293  x2ar[2] = x2h - rSize*cosT + sinT*dSize;
294  y2ar[2] = y2h - rSize*sinT - cosT*dSize;
295  x2ar[3] = x2ar[0];
296  y2ar[3] = y2ar[0];
297 
298  // NDC to user coordinates
299  for (Int_t i=0; i<4; i++) {
300  x2ar[i] = (1/rx)*(x2ar[i]-x1ndc)+rx1;
301  y2ar[i] = (1/ry)*(y2ar[i]-y1ndc)+ry1;
302  }
303  if (opt.Contains("|>")) {
304  if (gVirtualX) gVirtualX->SetLineStyle(1);
306  if (GetFillColor()) {
307  gPad->PaintFillArea(3,x2ar,y2ar);
308  gPad->PaintPolyLine(4,x2ar,y2ar);
309  } else {
310  gPad->PaintPolyLine(4,x2ar,y2ar);
311  }
312  } else {
313  gPad->PaintPolyLine(3,x2ar,y2ar);
314  }
315  }
316 
317  if (opt.Contains("<")) {
318  Double_t x1ar[4], y1ar[4];
319  x1ar[0] = x1h + rSize*cosT + sinT*dSize;
320  y1ar[0] = y1h + rSize*sinT - cosT*dSize;
321  x1ar[1] = x1h;
322  y1ar[1] = y1h;
323  x1ar[2] = x1h + rSize*cosT - sinT*dSize;
324  y1ar[2] = y1h + rSize*sinT + cosT*dSize;
325  x1ar[3] = x1ar[0];
326  y1ar[3] = y1ar[0];
327 
328  // NDC to user coordinates
329  for (Int_t i=0; i<4; i++) {
330  x1ar[i] = (1/rx)*(x1ar[i]-x1ndc)+rx1;
331  y1ar[i] = (1/ry)*(y1ar[i]-y1ndc)+ry1;
332  }
333  if (opt.Contains("<|")) {
334  if (gVirtualX) gVirtualX->SetLineStyle(1);
336  if (GetFillColor()) {
337  gPad->PaintFillArea(3,x1ar,y1ar);
338  gPad->PaintPolyLine(4,x1ar,y1ar);
339  } else {
340  gPad->PaintPolyLine(4,x1ar,y1ar);
341  }
342  } else {
343  gPad->PaintPolyLine(3,x1ar,y1ar);
344  }
345  }
346 }
347 
348 ////////////////////////////////////////////////////////////////////////////////
349 /// Save primitive as a C++ statement(s) on output stream out
350 
351 void TArrow::SavePrimitive(std::ostream &out, Option_t * /*= ""*/)
352 {
353 
354  char quote = '"';
355  if (gROOT->ClassSaved(TArrow::Class())) {
356  out<<" ";
357  } else {
358  out<<" TArrow *";
359  }
360  out<<"arrow = new TArrow("<<fX1<<","<<fY1<<","<<fX2<<","<<fY2
361  <<","<<fArrowSize<<","<<quote<<GetDrawOption()<<quote<<");"<<std::endl;
362 
363  SaveFillAttributes(out,"arrow",0,1);
364  SaveLineAttributes(out,"arrow",1,1,1);
365 
366  if (TestBit(kLineNDC))
367  out<<" arrow->SetNDC();"<<std::endl;
368 
369  if (fAngle!=60)
370  out << " arrow->SetAngle(" << GetAngle() << ");" << std::endl;
371 
372  out<<" arrow->Draw();"<<std::endl;
373 }
374 
375 
376 ////////////////////////////////////////////////////////////////////////////////
377 /// Set default angle.
378 
380 {
382 }
383 
384 
385 ////////////////////////////////////////////////////////////////////////////////
386 /// Set default arrow sive.
387 
389 {
390  fgDefaultArrowSize = ArrowSize;
391 }
392 
393 
394 ////////////////////////////////////////////////////////////////////////////////
395 /// Set default option.
396 
398 {
399 
400  fgDefaultOption = Option;
401 }
402 
403 
404 ////////////////////////////////////////////////////////////////////////////////
405 /// Get default angle.
406 
408 {
409 
410  return fgDefaultAngle;
411 }
412 
413 
414 ////////////////////////////////////////////////////////////////////////////////
415 /// Get default arrow size.
416 
418 {
419 
420  return fgDefaultArrowSize;
421 }
422 
423 
424 ////////////////////////////////////////////////////////////////////////////////
425 /// Get default option.
426 
428 {
429 
430  return fgDefaultOption.Data();
431 }
TArrow.h
TArrow::SetDefaultArrowSize
static void SetDefaultArrowSize(Float_t ArrowSize)
Set default arrow sive.
Definition: TArrow.cxx:388
TArrow::SetDefaultAngle
static void SetDefaultAngle(Float_t Angle)
Set default angle.
Definition: TArrow.cxx:379
TLine::fX1
Double_t fX1
X of 1st point.
Definition: TLine.h:25
TObject::TestBit
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
TArrow::fgDefaultArrowSize
static Float_t fgDefaultArrowSize
Default Arrow Size.
Definition: TArrow.h:36
TLine
A simple line.
Definition: TLine.h:22
Option_t
const char Option_t
Definition: RtypesCore.h:66
TLine::fX2
Double_t fX2
X of 2nd point.
Definition: TLine.h:27
TLine::kLineNDC
@ kLineNDC
Use NDC coordinates.
Definition: TLine.h:33
TArrow::PaintArrow
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:174
TAttFill::Modify
virtual void Modify()
Change current fill area attributes if necessary.
Definition: TAttFill.cxx:211
gVirtualX
#define gVirtualX
Definition: TVirtualX.h:338
TString::Data
const char * Data() const
Definition: TString.h:369
TArrow::GetOption
Option_t * GetOption() const
Definition: TArrow.h:53
TArrow::SetAngle
virtual void SetAngle(Float_t angle=60)
Definition: TArrow.h:58
ClassImp
#define ClassImp(name)
Definition: Rtypes.h:364
TArrow::Draw
virtual void Draw(Option_t *option="")
Draw this arrow with its current attributes.
Definition: TArrow.cxx:120
TArrow::fAngle
Float_t fAngle
Arrow opening angle (degrees)
Definition: TArrow.h:31
TMath::Sqrt
Double_t Sqrt(Double_t x)
Definition: TMath.h:691
TMath::Tan
Double_t Tan(Double_t)
Definition: TMath.h:647
Float_t
float Float_t
Definition: RtypesCore.h:57
Int_t
int Int_t
Definition: RtypesCore.h:45
TObject::AppendPad
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition: TObject.cxx:107
TString::Contains
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:624
TString::EndsWith
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2177
TAttLine::SaveLineAttributes
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:270
TString::Length
Ssiz_t Length() const
Definition: TString.h:410
TVirtualPS.h
TVirtualX.h
ROOT::Math::VectorUtil::Angle
double Angle(const Vector1 &v1, const Vector2 &v2)
Find Angle between two vectors.
Definition: VectorUtil.h:138
TArrow::SavePrimitive
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save primitive as a C++ statement(s) on output stream out.
Definition: TArrow.cxx:351
TArrow::GetAngle
Float_t GetAngle() const
Definition: TArrow.h:51
TString
Basic string class.
Definition: TString.h:136
TAttFill::SaveFillAttributes
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:234
TArrow::TArrow
TArrow()
Arrow default constructor.
Definition: TArrow.cxx:47
x1
static const double x1[5]
Definition: RooGaussKronrodIntegrator1D.cxx:346
TROOT.h
TAttLine::Modify
virtual void Modify()
Change current line attributes if necessary.
Definition: TAttLine.cxx:242
TArrow::fOption
TString fOption
Arrow shapes.
Definition: TArrow.h:33
TAttLine::Copy
void Copy(TAttLine &attline) const
Copy this line attributes to a new TAttLine.
Definition: TAttLine.cxx:172
TMath::Pi
constexpr Double_t Pi()
Definition: TMath.h:37
TAttFill::Copy
void Copy(TAttFill &attfill) const
Copy this fill attributes to a new TAttFill.
Definition: TAttFill.cxx:202
TLine::fY1
Double_t fY1
Y of 1st point.
Definition: TLine.h:26
TArrow::fArrowSize
Float_t fArrowSize
Arrow Size.
Definition: TArrow.h:32
TArrow::GetDefaultAngle
static Float_t GetDefaultAngle()
Get default angle.
Definition: TArrow.cxx:407
TAttLine::GetLineColor
virtual Color_t GetLineColor() const
Return the line color.
Definition: TAttLine.h:33
TObject::SetBit
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:696
TObject::GetDrawOption
virtual Option_t * GetDrawOption() const
Get option used by the graphics system to draw this object.
Definition: TObject.cxx:343
TArrow::GetDefaultArrowSize
static Float_t GetDefaultArrowSize()
Get default arrow size.
Definition: TArrow.cxx:417
TArrow::DrawArrow
virtual void 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
TVirtualPad.h
TArrow::GetDefaultOption
static Option_t * GetDefaultOption()
Get default option.
Definition: TArrow.cxx:427
TString::BeginsWith
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:615
TArrow::Copy
void Copy(TObject &arrow) const
Copy this arrow to arrow.
Definition: TArrow.cxx:108
TObject::kCanDelete
@ kCanDelete
if object in a list can be deleted
Definition: TObject.h:58
TMath::Min
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:180
gVirtualPS
R__EXTERN TVirtualPS * gVirtualPS
Definition: TVirtualPS.h:81
Double_t
double Double_t
Definition: RtypesCore.h:59
TArrow::fgDefaultAngle
static Float_t fgDefaultAngle
Default Arrow opening angle (degrees)
Definition: TArrow.h:35
TArrow::~TArrow
virtual ~TArrow()
Arrow default destructor.
Definition: TArrow.cxx:91
arrow
Definition: RArrowDS.hxx:9
TAttFill::SetFillColor
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition: TAttFill.h:37
TObject
Mother of all ROOT objects.
Definition: TObject.h:37
TArrow
Draw all kinds of Arrows.
Definition: TArrow.h:29
TArrow::fgDefaultOption
static TString fgDefaultOption
Default Arrow shapes.
Definition: TArrow.h:37
x2
static const double x2[5]
Definition: RooGaussKronrodIntegrator1D.cxx:364
gPad
#define gPad
Definition: TVirtualPad.h:287
TAttFill::GetFillColor
virtual Color_t GetFillColor() const
Return the fill area color.
Definition: TAttFill.h:30
TArrow::Paint
virtual void Paint(Option_t *option="")
Paint this arrow with its current attributes.
Definition: TArrow.cxx:156
TLine::fY2
Double_t fY2
Y of 2nd point.
Definition: TLine.h:28
TAttFill
Fill Area Attributes class.
Definition: TAttFill.h:19
TArrow::SetDefaultOption
static void SetDefaultOption(Option_t *Option)
Set default option.
Definition: TArrow.cxx:397
Class
void Class()
Definition: Class.C:29
TString::ToLower
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1125
TAttLine::SetLineStyle
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition: TAttLine.h:42
TLine::Copy
void Copy(TObject &line) const
Copy this line to line.
Definition: TLine.cxx:63
TMath.h
gROOT
#define gROOT
Definition: TROOT.h:406
int