point_2d.hpp
1 #pragma once
2 
3 #include <cmath>
4 #include <cassert>
5 
6 #include "global.hpp"
7 
8 #include "angle.hpp"
9 
10 namespace Cvb
11 {
12 
13 CVB_BEGIN_INLINE_NS
14 
16 
18 template< class T, class ENABLE = void>
19 class Point2D final
20 {
21 
22 #ifndef CVB_DOXYGEN
23  static_assert(std::is_arithmetic<T>::value, "CVB: Unsupported data type - must be arithmetic!");
24 };
25 
26 
27 template <class T>
28 class Point2D<T,
29  typename EnableIfArithmetic<T>::type> final
30 {
31 
32 #endif
33 
34  public:
35 
37 
40  Point2D() noexcept = default;
41 
42 
44 
49  Point2D(T x, T y) noexcept
50  : x_(x)
51  , y_(y)
52  {
53  }
54 
56 
63  Point2D(Angle phi, T r) noexcept
64  : Point2D(static_cast<T>(static_cast<double>(r) * Cos(phi)),
65  static_cast<T>(static_cast<double>(r) * Sin(phi)))
66  {
67  }
68 
70 
74  template<std::size_t N>
75  Point2D(const T(&list)[N]) noexcept
76  {
77  static_assert(N == 2, "CVB: Point2D must have 2 elements");
78  std::copy(std::begin(list), std::end(list), &x_);
79  }
80 
82 
86  T X() const noexcept
87  {
88  return x_;
89  }
90 
92 
96  void SetX(T x) noexcept
97  {
98  x_ = x;
99  }
100 
102 
106  T Y() const noexcept
107  {
108  return y_;
109  }
110 
112 
116  void SetY(T y)
117  {
118  y_ = y;
119  }
120 
122 
126  T Length() const noexcept
127  {
128  return static_cast<T>(sqrt(static_cast<double>(x_) * static_cast<double>(x_)
129  + static_cast<double>(y_) * static_cast<double>(y_)));
130  }
131 
133 
137  void SetLength(T length) noexcept
138  {
139  *this = Point2D<T>(Phi(), length);
140  }
141 
143 
147  Angle Phi() const noexcept
148  {
149  return Atan2(static_cast<double>(y_), static_cast<double>(x_));
150  }
151 
153 
157  void SetPhi(Angle phi) noexcept
158  {
159  *this = Point2D<T>(phi, Length());
160  }
161 
162 
163 
164 
166 
171  bool operator==(const Point2D<T>& other) const noexcept
172  {
173  return (x_ == other.x_ && y_ == other.y_);
174  }
175 
176 
178 
183  bool operator!=(const Point2D<T>& other) const noexcept
184  {
185  return !(*this == other);
186  }
187 
189  template <class C>
190  explicit operator Point2D<C>() const noexcept
191  {
192  static_assert(std::is_floating_point<C>::value, "CVB: Unsupported data type - must be floating point!");
193  return Point2D<C>(static_cast<C>(X()), static_cast<C>(Y()));
194  }
195 
197 
202  Point2D<T>& operator +=(const Point2D<T> & point) noexcept
203  {
204  x_ += point.x_;
205  y_ += point.y_;
206  return *this;
207  }
208 
210 
215  Point2D<T>& operator -=(const Point2D<T> & point) noexcept
216  {
217  x_ -= point.x_;
218  y_ -= point.y_;
219  return *this;
220  }
221 
223 
228  Point2D<T>& operator *=(const T & value) noexcept
229  {
230  x_ *= value;
231  y_ *= value;
232  return *this;
233  }
234 
236 
241  Point2D<T>& operator /=(const T & value) noexcept
242  {
243  x_ /= value;
244  y_ /= value;
245  return *this;
246  }
247 
248 
250 
255  const T& operator[](int index) const noexcept
256  {
257  assert(index < 2 && index >= 0);
258  return *(&x_ + index);
259  }
260 
262 
267  T& operator[](int index) noexcept
268  {
269  assert(index < 2 && index >= 0);
270  return *(&x_ + index);
271  }
272 
273  private:
274 
275  T x_ = static_cast<T>(0);
276  T y_ = static_cast<T>(0);
277 
278 
279 };
280 
282 
290 template <class T>
291 inline Point2D<T> operator+(const Point2D<T> & lhs, const Point2D<T> & rhs)
292 {
293  return Point2D<T>(lhs.X() + rhs.X(), lhs.Y() + rhs.Y());
294 }
295 
297 
305 template <class T>
306 inline Point2D<T> operator-(const Point2D<T> & lhs, const Point2D<T> & rhs)
307 {
308  return Point2D<T>(lhs.X() - rhs.X(), lhs.Y() - rhs.Y());
309 }
310 
312 
320 template <class T>
321 inline T operator*(const Point2D<T> & lhs, const Point2D<T> & rhs)
322 {
323  return lhs.X() * rhs.X() + lhs.Y() * rhs.Y();
324 }
325 
327 
335 template <class T>
336 inline Point2D<T> operator*(const Point2D<T> & lhs, const T & rhs)
337 {
338  return Point2D<T>(lhs.X() * rhs, lhs.Y() * rhs);
339 }
340 
342 
350 template <class T>
351 inline Point2D<T> operator*(const T & lhs, const Point2D<T> & rhs)
352 {
353  return rhs * lhs;
354 }
355 
357 
365 template <class T>
366 inline Point2D<T> operator/(const Point2D<T> & lhs, const T & rhs)
367 {
368  return Point2D<T>(lhs.X() / rhs, lhs.Y() / rhs);
369 }
370 
372 
379 template <class T>
380 inline Point2D<int> Round(const Point2D<T> & rhs) noexcept
381 {
382  static_assert(IsNumeric<T>::value, "CVB: Unsupported data type - must be numeric!");
383  return Point2D<int>(static_cast<int>(std::round(rhs.X())), static_cast<int>(std::round(rhs.Y())));
384 }
385 
387 template<class T>
389 
390 CVB_END_INLINE_NS
391 
392 
393 }
void SetPhi(Angle phi) noexcept
Sets the orientation of the vector represented by this point object.
Definition: point_2d.hpp:157
Point2D< T > & operator *=(const T &value) noexcept
Multiplies by a scalar and assigns to this point.
Definition: point_2d.hpp:228
double Cos(Angle angle) noexcept
Returns the cosine of an angle.
Definition: angle.hpp:411
T Length() const noexcept
Gets the length of the vector represented by this point object.
Definition: point_2d.hpp:126
Point2D< int > Round(const Point2D< T > &rhs) noexcept
Round to an integer point.
Definition: point_2d.hpp:380
Angle Phi() const noexcept
Gets the orientation of the vector represented by this point object.
Definition: point_2d.hpp:147
AffineMatrix2D operator+(const AffineMatrix2D &lhs, const AffineMatrix2D &rhs) noexcept
Add two affine matrices.
Definition: affine_matrix_2d.hpp:217
Point2D< T > & operator -=(const Point2D< T > &point) noexcept
Subtracts and assigns to this point.
Definition: point_2d.hpp:215
Point2D(Angle phi, T r) noexcept
Create a PointD vector from radial coordinates.
Definition: point_2d.hpp:63
bool operator!=(const Point2D< T > &other) const noexcept
Compares to an other point.
Definition: point_2d.hpp:183
AffineMatrix2D operator/(const AffineMatrix2D &lhs, const double &rhs)
Divide affine matrix by scalar.
Definition: affine_matrix_2d.hpp:301
double Sin(Angle angle) noexcept
Returns the sine of an angle.
Definition: angle.hpp:438
bool operator==(const Point2D< T > &other) const noexcept
Compares to an other point.
Definition: point_2d.hpp:171
Root namespace for the Image Manager interface.
Definition: version.hpp:11
Point2D< T > & operator+=(const Point2D< T > &point) noexcept
Adds and assigns to this point.
Definition: point_2d.hpp:202
T Y() const noexcept
Gets the y-component of the point.
Definition: point_2d.hpp:106
Multi-purpose 2D vector class.
Definition: point_2d.hpp:19
AffineMatrix2D operator *(const AffineMatrix2D &lhs, const AffineMatrix2D &rhs) noexcept
Multiply two affine matrices.
Definition: affine_matrix_2d.hpp:245
void SetY(T y)
Sets the y-component of the point.
Definition: point_2d.hpp:116
T X() const noexcept
Gets the x-component of the point.
Definition: point_2d.hpp:86
T & operator[](int index) noexcept
Index based element access.
Definition: point_2d.hpp:267
const T & operator[](int index) const noexcept
Index based element access.
Definition: point_2d.hpp:255
void SetLength(T length) noexcept
Sets the length of the vector represented by this point object.
Definition: point_2d.hpp:137
void SetX(T x) noexcept
Sets the x-component of the point.
Definition: point_2d.hpp:96
Point2D(const T(&list)[N]) noexcept
Construct a point with an initializer list.
Definition: point_2d.hpp:75
Angle Atan2(double y, double x) noexcept
Returns the angle whose tangent is the quotient of two specified numbers.
Definition: angle.hpp:397
Point2D< T > & operator/=(const T &value) noexcept
Divide by a scalar and assigns to this point.
Definition: point_2d.hpp:241
Point2D() noexcept=default
Creates a default point at (0, 0).
AffineMatrix2D operator-(const AffineMatrix2D &lhs, const AffineMatrix2D &rhs) noexcept
Subtract two affine matrices.
Definition: affine_matrix_2d.hpp:231
Object for convenient and type - safe handling of angles.
Definition: angle.hpp:18