Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
RPadLength.hxx
Go to the documentation of this file.
1 /// \defgroup ROOT7PadCoordSystems ROOT7 RPad coordinate systems
2 /// \ingroup ROOT7Graphics
3 /// \brief The ROOT7 RPad coordinate systems.
4 ///
5 /// \author Axel Naumann <axel@cern.ch>
6 /// \date 2017-07-06
7 
8 /*************************************************************************
9  * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers. *
10  * All rights reserved. *
11  * *
12  * For the licensing terms see $ROOTSYS/LICENSE. *
13  * For the list of contributors see $ROOTSYS/README/CREDITS. *
14  *************************************************************************/
15 
16 #ifndef ROOT7_RPadLength
17 #define ROOT7_RPadLength
18 
19 #include <vector>
20 #include <string>
21 
22 namespace ROOT {
23 namespace Experimental {
24 
25  /** \class RPadLength
26  \ingroup ROOT7PadCoordSystems
27  \brief A length in RPad.
28  */
29 
30 class RPadLength {
31 
32 protected:
33 
34  std::vector<double> fArr; ///< components [0] - normalized, [1] - pixel, [2] - user
35 
36 public:
37  template <class DERIVED>
38  struct CoordSysBase {
39  double fVal{0.}; ///<! Coordinate value
40 
41  CoordSysBase() = default;
42  CoordSysBase(double val): fVal(val) {}
43  DERIVED &ToDerived() { return static_cast<DERIVED &>(*this); }
44 
45  DERIVED operator-() { return DERIVED(-fVal); }
46 
47  friend DERIVED operator+(DERIVED lhs, DERIVED rhs) { return DERIVED{lhs.fVal + rhs.fVal}; }
48  friend DERIVED operator-(DERIVED lhs, DERIVED rhs) { return DERIVED{lhs.fVal - rhs.fVal}; }
49  friend double operator/(DERIVED lhs, DERIVED rhs) { return lhs.fVal / rhs.fVal; }
50  DERIVED &operator+=(const DERIVED &rhs)
51  {
52  fVal += rhs.fVal;
53  return ToDerived();
54  }
55  DERIVED &operator-=(const DERIVED &rhs)
56  {
57  fVal -= rhs.fVal;
58  return ToDerived();
59  }
60  DERIVED &operator*=(double scale)
61  {
62  fVal *= scale;
63  return ToDerived();
64  }
65  friend DERIVED operator*(const DERIVED &lhs, double rhs) { return DERIVED(lhs.fVal * rhs); }
66  friend DERIVED operator*(double lhs, const DERIVED &rhs) { return DERIVED(lhs * rhs.fVal); }
67  friend DERIVED operator/(const DERIVED &lhs, double rhs) { return DERIVED(lhs.fVal * rhs); }
68  friend bool operator<(const DERIVED &lhs, const DERIVED &rhs) { return lhs.fVal < rhs.fVal; }
69  friend bool operator>(const DERIVED &lhs, const DERIVED &rhs) { return lhs.fVal > rhs.fVal; }
70  friend bool operator<=(const DERIVED &lhs, const DERIVED &rhs) { return lhs.fVal <= rhs.fVal; }
71  friend bool operator>=(const DERIVED &lhs, const DERIVED &rhs) { return lhs.fVal >= rhs.fVal; }
72  // no ==, !=
73  };
74 
75  /// \defgroup TypesafeCoordinates Typesafe Coordinates
76  /// \ingroup ROOT7PadCoordSystems
77  /// These define typesafe coordinates used by RPad to identify which coordinate system a coordinate is referring to
78  /// The origin (0,0) is in the `RPad`'s bottom left corner for all of them.
79  /// \{
80 
81  /** \struct Normal
82  \brief A normalized coordinate.
83 
84  0 in the left, bottom corner, 1 in the top, right corner of the `RPad`.
85  Resizing the pad will resize the objects with it.
86  */
87  struct Normal: CoordSysBase<Normal> {
88  using CoordSysBase<Normal>::CoordSysBase;
89  };
90 
91  /** \struct Pixel
92  \brief A pixel coordinate.
93 
94  0 in the left, bottom corner, 1 in the top, right corner of the `RPad`.
95  Resizing the pad will keep the pixel-position of the objects positioned in `Pixel` coordinates.
96  */
97  struct Pixel: CoordSysBase<Pixel> {
98  using CoordSysBase<Pixel>::CoordSysBase;
99  };
100 
101  /** \struct User
102  \brief A user coordinate.
103 
104  as defined by the EUserCoordSystem parameter of the `RPad`.
105  */
106  struct User: CoordSysBase<User> {
107  using CoordSysBase<User>::CoordSysBase;
108  };
109  /// \}
110 
111  RPadLength() {}
112 
113  /// Constructor from a `Normal` coordinate.
114  RPadLength(Normal normal): RPadLength() { SetNormal(normal.fVal); }
115 
116  /// Constructor from a `Pixel` coordinate.
117  RPadLength(Pixel px): RPadLength() { SetPixel(px.fVal); }
118 
119  /// Constructor from a `User` coordinate.
120  RPadLength(User user) : RPadLength() { SetUser(user.fVal); }
121 
122  /// Constructor for normal and pixel coordinate.
123  RPadLength(Normal normal, Pixel px): RPadLength() { SetPixel(px.fVal); SetNormal(normal.fVal); }
124 
125  /// Constructor for normal, pixel and user coordinate.
126  RPadLength(Normal normal, Pixel px, User user): RPadLength() { SetUser(user.fVal); SetPixel(px.fVal); SetNormal(normal.fVal); }
127 
128  bool HasNormal() const { return fArr.size() > 0; }
129  bool HasPixel() const { return fArr.size() > 1; }
130  bool HasUser() const { return fArr.size() > 2; }
131 
132  RPadLength &SetNormal(double v)
133  {
134  if (fArr.size() < 1)
135  fArr.resize(1);
136  fArr[0] = v;
137  return *this;
138  }
139  RPadLength &SetPixel(double v)
140  {
141  if (fArr.size() < 2)
142  fArr.resize(2, 0.);
143  fArr[1] = v;
144  return *this;
145  }
146  RPadLength &SetUser(double v)
147  {
148  if (fArr.size() < 3)
149  fArr.resize(3, 0.);
150  fArr[2] = v;
151  return *this;
152  }
153 
154  double GetNormal() const { return fArr.size() > 0 ? fArr[0] : 0.; }
155  double GetPixel() const { return fArr.size() > 1 ? fArr[1] : 0.; }
156  double GetUser() const { return fArr.size() > 2 ? fArr[2] : 0.; }
157 
158  void ClearUser() { if (fArr.size()>2) fArr.resize(2); }
159 
160  void Clear() { fArr.clear(); }
161 
162  /// Add two `RPadLength`s.
163  friend RPadLength operator+(RPadLength lhs, const RPadLength &rhs)
164  {
165  RPadLength res;
166  if (lhs.HasUser() || rhs.HasUser())
167  res.SetUser(lhs.GetUser() + rhs.GetUser());
168  if (lhs.HasPixel() || rhs.HasPixel())
169  res.SetPixel(lhs.GetPixel() + rhs.GetPixel());
170  if (lhs.HasNormal() || rhs.HasNormal())
171  res.SetNormal(lhs.GetNormal() + rhs.GetNormal());
172  return res;
173  }
174 
175  /// Subtract two `RPadLength`s.
176  friend RPadLength operator-(RPadLength lhs, const RPadLength &rhs)
177  {
178  RPadLength res;
179  if (lhs.HasUser() || rhs.HasUser())
180  res.SetUser(lhs.GetUser() - rhs.GetUser());
181  if (lhs.HasPixel() || rhs.HasPixel())
182  res.SetPixel(lhs.GetPixel() - rhs.GetPixel());
183  if (lhs.HasNormal() || rhs.HasNormal())
184  res.SetNormal(lhs.GetNormal() - rhs.GetNormal());
185  return res;
186  }
187 
188  /// Unary -.
189  RPadLength operator-()
190  {
191  RPadLength res;
192  if (HasUser()) res.SetUser(-GetUser());
193  if (HasPixel()) res.SetPixel(-GetPixel());
194  if (HasNormal()) res.SetNormal(-GetNormal());
195  return res;
196  }
197 
198  /// Add a `RPadLength`.
199  RPadLength &operator+=(const RPadLength &rhs)
200  {
201  if (HasUser() || rhs.HasUser())
202  SetUser(GetUser() + rhs.GetUser());
203  if (HasPixel() || rhs.HasPixel())
204  SetPixel(GetPixel() + rhs.GetPixel());
205  if (HasNormal() || rhs.HasNormal())
206  SetNormal(GetNormal() + rhs.GetNormal());
207  return *this;
208  };
209 
210  /// Subtract a `RPadLength`.
211  RPadLength &operator-=(const RPadLength &rhs)
212  {
213  if (HasUser() || rhs.HasUser())
214  SetUser(GetUser() - rhs.GetUser());
215  if (HasPixel() || rhs.HasPixel())
216  SetPixel(GetPixel() - rhs.GetPixel());
217  if (HasNormal() || rhs.HasNormal())
218  SetNormal(GetNormal() - rhs.GetNormal());
219  return *this;
220  };
221 
222  RPadLength &operator*=(double scale)
223  {
224  if (HasUser()) SetUser(scale*GetUser());
225  if (HasPixel()) SetPixel(scale*GetPixel());
226  if (HasNormal()) SetNormal(scale*GetNormal());
227  return *this;
228  }
229 
230 };
231 
232 /// User-defined literal for `RPadLength::Normal`
233 ///
234 /// Use as
235 /// ```
236 /// using namespace ROOT::Experimental;
237 /// RLine(0.1_normal, 0.0_normal, RLineExtent(0.2_normal, 0.5_normal));
238 /// ```
239 inline RPadLength::Normal operator"" _normal(long double val)
240 {
241  return RPadLength::Normal{(double)val};
242 }
243 inline RPadLength::Normal operator"" _normal(unsigned long long int val)
244 {
245  return RPadLength::Normal{(double)val};
246 }
247 
248 /// User-defined literal for `RPadLength::Pixel`
249 ///
250 /// Use as
251 /// ```
252 /// using namespace ROOT::Experimental;
253 /// RLine(100_px, 0_px, RLineExtent(20_px, 50_px));
254 /// ```
255 inline RPadLength::Pixel operator"" _px(long double val)
256 {
257  return RPadLength::Pixel{(double)val};
258 }
259 inline RPadLength::Pixel operator"" _px(unsigned long long int val)
260 {
261  return RPadLength::Pixel{(double)val};
262 }
263 
264 /// User-defined literal for `RPadLength::User`
265 ///
266 /// Use as
267 /// ```
268 /// using namespace ROOT::Experimental;
269 /// RLine(0.1_user, 0.0_user, RLineExtent(0.2_user, 0.5_user));
270 /// ```
271 inline RPadLength::User operator"" _user(long double val)
272 {
273  return RPadLength::User{(double)val};
274 }
275 inline RPadLength::User operator"" _user(unsigned long long int val)
276 {
277  return RPadLength::User{(double)val};
278 }
279 
280 } // namespace Experimental
281 } // namespace ROOT
282 
283 #endif