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