point_3d.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 
15 #pragma pack ( push, 4 )
16 
18 
20 template< class T, class ENABLE = void>
21 class Point3D final
22 {
23 
24 #ifndef CVB_DOXYGEN
25  static_assert (std::is_arithmetic<T>::value, "CVB: Unsupported data type - must be arithmetic!");
26 };
27 
28 
29 template <class T>
30 class Point3D<T,
31  typename EnableIfArithmetic<T>::type> final
32 {
33 
34 #endif
35 
36  public:
37 
38  using ValueType = T;
39 
41 
44  Point3D() noexcept = default;
45 
46 
48 
54  Point3D(T x, T y, T z) noexcept
55  : x_(x)
56  , y_(y)
57  , z_(z)
58  {
59  }
60 
61 
63 
67  template<std::size_t N>
68  Point3D(const T(&list)[N]) noexcept
69  {
70  static_assert(N == 3, "CVB: Point3D must have 3 elements");
71  std::copy(std::begin(list), std::end(list), &x_);
72  }
73 
74 
76 
80  T X() const noexcept
81  {
82  return x_;
83  }
84 
86 
90  void SetX(T x) noexcept
91  {
92  x_ = x;
93  }
94 
96 
100  T Y() const noexcept
101  {
102  return y_;
103  }
104 
106 
110  void SetY(T y)
111  {
112  y_ = y;
113  }
114 
116 
120  T Z() const noexcept
121  {
122  return z_;
123  }
124 
126 
130  void SetZ(T z)
131  {
132  z_ = z;
133  }
134 
136 
140  T Length() const noexcept
141  {
142  return sqrt(x_ * x_ + y_ * y_ + z_ * z_);
143  }
144 
145 
146 
148 
153  bool operator==(const Point3D<T>& other) const noexcept
154  {
155  return (x_ == other.x_ && y_ == other.y_ && z_ == other.z_);
156  }
157 
158 
160 
165  bool operator!=(const Point3D<T>& other) const noexcept
166  {
167  return !(*this == other);
168  }
169 
171  template <class C>
172  explicit operator Point3D<C>() const noexcept
173  {
174  static_assert(std::is_floating_point<C>::value, "CVB: Unsupported data type - must be floating point!");
175  return Point3D<C>(static_cast<C>(X()), static_cast<C>(Y()), static_cast<C>(Z()));
176  }
177 
179 
184  Point3D<T>& operator +=(const Point3D<T> & point) noexcept
185  {
186  x_ += point.x_;
187  y_ += point.y_;
188  z_ += point.z_;
189  return *this;
190  }
191 
193 
198  Point3D<T>& operator -=(const Point3D<T> & point) noexcept
199  {
200  x_ -= point.x_;
201  y_ -= point.y_;
202  z_ -= point.z_;
203  return *this;
204  }
205 
207 
212  Point3D<T>& operator *=(const T & value) noexcept
213  {
214  x_ *= value;
215  y_ *= value;
216  z_ *= value;
217  return *this;
218  }
219 
221 
226  Point3D<T>& operator /=(const T & value) noexcept
227  {
228  x_ /= value;
229  y_ /= value;
230  z_ /= value;
231  return *this;
232  }
233 
234 
236 
241  const T& operator[](int index) const noexcept
242  {
243  assert(index < 3 && index >= 0);
244  return *(&x_ + index);
245  }
246 
248 
253  T& operator[](int index) noexcept
254  {
255  assert(index < 3 && index >= 0);
256  return *(&x_ + index);
257  }
258 
259  private:
260 
261  T x_ = static_cast<T>(0.0);
262  T y_ = static_cast<T>(0.0);
263  T z_ = static_cast<T>(0.0);
264 
265 
266 };
267 
269 
277 template <class T>
278 inline Point3D<T> operator+(const Point3D<T> & lhs, const Point3D<T> & rhs)
279 {
280  return Point3D<T>(lhs.X() + rhs.X(), lhs.Y() + rhs.Y(), lhs.Z() + rhs.Z());
281 }
282 
284 
292 template <class T>
293 inline Point3D<T> operator-(const Point3D<T> & lhs, const Point3D<T> & rhs)
294 {
295  return Point3D<T>(lhs.X() - rhs.X(), lhs.Y() - rhs.Y(), lhs.Z() - rhs.Z());
296 }
297 
299 
307 template <class T>
308 inline T operator*(const Point3D<T> & lhs, const Point3D<T> & rhs)
309 {
310  return lhs.X() * rhs.X() + lhs.Y() * rhs.Y() + lhs.Z() * rhs.Z();
311 }
312 
314 
322 template <class T>
323 inline Point3D<T> operator*(const Point3D<T> & lhs, const T & rhs)
324 {
325  return Point3D<T>(lhs.X() * rhs, lhs.Y() * rhs, lhs.Z() * rhs);
326 }
327 
329 
337 template <class T>
338 inline Point3D<T> operator*(const T & lhs, const Point3D<T> & rhs)
339 {
340  return rhs * lhs;
341 }
342 
344 
352 template <class T>
353 inline Point3D<T> operator/(const Point3D<T> & lhs, const T & rhs)
354 {
355  return Point3D<T>(lhs.X() / rhs, lhs.Y() / rhs, lhs.Z() / rhs);
356 }
357 
358 
360 
367 template <class T>
368 inline Point3D<int> Round(const Point3D<T> & rhs) noexcept
369 {
370  static_assert(IsNumeric<T>::value, "CVB: Unsupported data type - must be numeric!");
371  return Point3D<int>(static_cast<int>(std::round(rhs.X())), static_cast<int>(std::round(rhs.Y())), static_cast<int>(std::round(rhs.Z())) );
372 }
373 
374 
376 template<class T>
378 
379 #pragma pack ( pop )
380 
381 CVB_END_INLINE_NS
382 
383 
384 }
T X() const noexcept
Get the x component of the point.
Definition: point_3d.hpp:80
Point3D() noexcept=default
Creates a default point at (0, 0).
Point2D< int > Round(const Point2D< T > &rhs) noexcept
Round to an integer point.
Definition: point_2d.hpp:380
void SetY(T y)
Set the y component of the point.
Definition: point_3d.hpp:110
AffineMatrix2D operator/(const AffineMatrix2D &lhs, const double &rhs)
Divide affine matrix by scalar.
Definition: affine_matrix_2d.hpp:301
T Length() const noexcept
Gets the length of this point.
Definition: point_3d.hpp:140
Point3D< T > & operator -=(const Point3D< T > &point) noexcept
Subtracts and assigns to this point.
Definition: point_3d.hpp:198
Root namespace for the Image Manager interface.
Definition: version.hpp:11
void SetX(T x) noexcept
Set the x component of the point.
Definition: point_3d.hpp:90
Multi-purpose 3D vector class.
Definition: point_3d.hpp:21
AffineMatrix2D operator *(const AffineMatrix2D &lhs, const AffineMatrix2D &rhs) noexcept
Multiply two affine matrices.
Definition: affine_matrix_2d.hpp:245
void SetZ(T z)
Set the z component of the point.
Definition: point_3d.hpp:130
Point3D< T > & operator *=(const T &value) noexcept
Multiplies by a scalar and assigns to this point.
Definition: point_3d.hpp:212
Point3D< T > operator+(const Point3D< T > &lhs, const Point3D< T > &rhs)
Add two points.
Definition: point_3d.hpp:278
T & operator[](int index) noexcept
Index based element access.
Definition: point_3d.hpp:253
bool operator!=(const Point3D< T > &other) const noexcept
Compares to an other point.
Definition: point_3d.hpp:165
bool operator==(const Point3D< T > &other) const noexcept
Compares to an other point.
Definition: point_3d.hpp:153
Point3D(const T(&list)[N]) noexcept
Construct a point with an initializer list.
Definition: point_3d.hpp:68
T Z() const noexcept
Get the z component of the point.
Definition: point_3d.hpp:120
Point3D< T > & operator+=(const Point3D< T > &point) noexcept
Adds and assigns to this point.
Definition: point_3d.hpp:184
const T & operator[](int index) const noexcept
Index based element access.
Definition: point_3d.hpp:241
AffineMatrix2D operator-(const AffineMatrix2D &lhs, const AffineMatrix2D &rhs) noexcept
Subtract two affine matrices.
Definition: affine_matrix_2d.hpp:231
Point3D< T > & operator/=(const T &value) noexcept
Divide by a scalar and assigns to this point.
Definition: point_3d.hpp:226
T Y() const noexcept
Get the y component of the point.
Definition: point_3d.hpp:100