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