matrix_3d.hpp
1 #pragma once
2 
3 
4 
5 #include "_cexports/c_core_3d.h"
6 
7 #include "global.hpp"
8 
9 
10 #include "point_3d.hpp"
11 
12 namespace Cvb
13 {
14 
15 CVB_BEGIN_INLINE_NS
16 
17 
18 class Matrix3D;
19 
20 
22 
30 inline Matrix3D operator+(const Matrix3D & lhs, const Matrix3D & rhs);
31 
33 
41 inline Matrix3D operator-(const Matrix3D & lhs, const Matrix3D & rhs);
42 
43 
45 
53 inline Matrix3D operator*(const Matrix3D & lhs, const Matrix3D & rhs);
54 
56 
58 class Matrix3D final
59 {
60  public:
61 
63 
67  static Matrix3D Identity() noexcept
68  {
69  return {{
70  1.0, 0.0, 0.0,
71  0.0, 1.0, 0.0,
72  0.0, 0.0, 1.0
73  }};
74  }
75 
77 
80  Matrix3D() noexcept = default;
81 
83 
87  template<std::size_t N>
88  Matrix3D(const double(&list)[N]) noexcept
89  {
90  static_assert(N == 9, "CVB: Matrix3D must have 9 elements");
91  std::copy(std::begin(list), std::end(list), matrix_.data()->data());
92  }
93 
94 
96 
102  Matrix3D(double roll, double pitch, double yaw)
103  {
104  Internal::DoResCall([&]()
105  {
106  auto thisData = reinterpret_cast<CExports::CVC3DMatrix*>(this);
107  return CVB_CALL_CAPI(CVC3DRotationMatrixFromRollPitchYaw(roll, pitch, yaw, *thisData));
108  });
109 
110  }
111 
113 
122  void RollPitchYaw(double & roll, double & pitch, double & yaw) const
123  {
124  Internal::DoResCall([&]()
125  {
126  auto thisData = reinterpret_cast<const CExports::CVC3DMatrix*>(this);
127  return CVB_CALL_CAPI(CVC3DRollPitchYawFromRotationMatrix(*thisData, roll, pitch, yaw));
128  });
129 
130  }
131 
133 
138  const double* operator[](int row) const noexcept
139  {
140  return matrix_[row].data();
141  }
142 
143 
145 
150  double* operator[](int row) noexcept
151  {
152  return matrix_[row].data();
153  }
154 
156 
162  const double& At(int row, int column) const noexcept
163  {
164  return (*this)[row][column];
165  }
166 
168 
174  double& At(int row, int column) noexcept
175  {
176  return (*this)[row][column];
177  }
178 
180 
184  double Det() const
185  {
186  return Internal::DoResCallValueOut<double>([&](double & value)
187  {
188  auto thisData = reinterpret_cast<const CExports::CVC3DMatrix*>(this);
189  return CVB_CALL_CAPI(CVC3DMatrixDeterminant(*thisData, value));
190  });
191  }
192 
193 
195 
200  void Invert()
201  {
202  Internal::DoResCall([&]()
203  {
204  auto data = reinterpret_cast<const CExports::CVC3DMatrix*>(this);
205  auto dataInv = reinterpret_cast<CExports::CVC3DMatrix*>(this);
206  return CVB_CALL_CAPI(CVC3DInvertMatrix(*data, *dataInv));
207  });
208  }
209 
211 
216  bool operator==(const Matrix3D& matrix) const noexcept
217  {
218  return matrix_ == matrix.matrix_;
219  }
220 
222 
227  bool operator!=(const Matrix3D& matrix) const noexcept
228  {
229  return !(*this == matrix);
230  }
231 
233 
238  Matrix3D& operator +=(const Matrix3D & matrix) noexcept
239  {
240  *this = *this + matrix;
241  return *this;
242  }
243 
245 
250  Matrix3D& operator -=(const Matrix3D & matrix) noexcept
251  {
252  *this = *this - matrix;
253  return *this;
254  }
255 
257 
262  Matrix3D& operator *=(const Matrix3D & matrix)
263  {
264  *this = *this * matrix;
265  return *this;
266  }
267 
269 
274  Matrix3D& operator *=(const double & value) noexcept
275  {
276  for (auto & line : matrix_)
277  for (auto & element : line)
278  element *= value;
279  return *this;
280  }
281 
283 
288  Matrix3D& operator /=(const double & value) noexcept
289  {
290  for(auto & line : matrix_)
291  for(auto & element : line)
292  element /= value;
293  return *this;
294  }
295 
296 
297 
298  private:
299 
300 
301  std::array<std::array<double, 3>, 3> matrix_{};
302 };
303 
304 
305 
306 
307 inline Matrix3D operator+(const Matrix3D & lhs, const Matrix3D & rhs)
308 {
309  return
310  {{
311  lhs[0][0] + rhs[0][0], lhs[0][1] + rhs[0][1], lhs[0][2] + rhs[0][2],
312  lhs[1][0] + rhs[1][0], lhs[1][1] + rhs[1][1], lhs[1][2] + rhs[1][2],
313  lhs[2][0] + rhs[2][0], lhs[2][1] + rhs[2][1], lhs[2][2] + rhs[2][2],
314  }};
315 }
316 
317 
318 inline Matrix3D operator-(const Matrix3D & lhs, const Matrix3D & rhs)
319 {
320  return
321  { {
322  lhs[0][0] - rhs[0][0], lhs[0][1] - rhs[0][1], lhs[0][2] - rhs[0][2],
323  lhs[1][0] - rhs[1][0], lhs[1][1] - rhs[1][1], lhs[1][2] - rhs[1][2],
324  lhs[2][0] - rhs[2][0], lhs[2][1] - rhs[2][1], lhs[2][2] - rhs[2][2],
325  } };
326 }
327 
328 
329 inline Matrix3D operator*(const Matrix3D & lhs, const Matrix3D & rhs)
330 {
331 
332  return Internal::DoResCallValueOut<Matrix3D>([&](Matrix3D & value)
333  {
334  auto valueData = reinterpret_cast<CExports::CVC3DMatrix*>(&value);
335  auto lhsData = reinterpret_cast<const CExports::CVC3DMatrix*>(&lhs);
336  auto rhsData = reinterpret_cast<const CExports::CVC3DMatrix*>(&rhs);
337  return CVB_CALL_CAPI(CVC3DMultiplyMatrices(*lhsData,
338  *rhsData,
339  *valueData));
340  });
341 
342 }
343 
345 
353 inline Point3D<double> operator*(const Matrix3D & lhs, const Point3D<double> & rhs)
354 {
355  return
356  {{
357  lhs[0][0] * rhs[0] + lhs[0][1] * rhs[1] + lhs[0][2] * rhs[2],
358  lhs[1][0] * rhs[0] + lhs[1][1] * rhs[1] + lhs[1][2] * rhs[2],
359  lhs[2][0] * rhs[0] + lhs[2][1] * rhs[1] + lhs[2][2] * rhs[2],
360  }};
361 }
362 
364 
372 inline Matrix3D operator*(const Matrix3D & lhs, const double & rhs)
373 {
374  return
375  {{
376  lhs[0][0] * rhs, lhs[0][1] * rhs, lhs[0][2] * rhs,
377  lhs[1][0] * rhs, lhs[1][1] * rhs, lhs[1][2] * rhs,
378  lhs[2][0] * rhs, lhs[2][1] * rhs, lhs[2][2] * rhs
379  }};
380 }
381 
383 
391 inline Matrix3D operator*(const double & lhs, const Matrix3D & rhs)
392 {
393  return rhs * lhs;
394 }
395 
397 
405 inline Matrix3D operator/(const Matrix3D & lhs, const double & rhs)
406 {
407  return
408  {{
409  lhs[0][0] / rhs, lhs[0][1] / rhs, lhs[0][2] / rhs,
410  lhs[1][0] / rhs, lhs[1][1] / rhs, lhs[1][2] / rhs,
411  lhs[2][0] / rhs, lhs[2][1] / rhs, lhs[2][2] / rhs
412  }};
413 }
414 
415 
416 
417 
418 
419 
420 CVB_END_INLINE_NS
421 
422 }
Matrix3D & operator+=(const Matrix3D &matrix) noexcept
Adds and assigns to this matrix.
Definition: matrix_3d.hpp:238
AffineMatrix2D operator+(const AffineMatrix2D &lhs, const AffineMatrix2D &rhs) noexcept
Add two affine matrices.
Definition: affine_matrix_2d.hpp:217
void RollPitchYaw(double &roll, double &pitch, double &yaw) const
Computes the Euler angles Roll, Pitch and Yaw for this matrix.
Definition: matrix_3d.hpp:122
bool operator!=(const Matrix3D &matrix) const noexcept
Compares to an other matrix.
Definition: matrix_3d.hpp:227
static Matrix3D Identity() noexcept
The identity element.
Definition: matrix_3d.hpp:67
Matrix3D & operator *=(const double &value) noexcept
Multiplies and assigns to this matrix.
Definition: matrix_3d.hpp:274
AffineMatrix2D operator/(const AffineMatrix2D &lhs, const double &rhs)
Divide affine matrix by scalar.
Definition: affine_matrix_2d.hpp:301
double & At(int row, int column) noexcept
Index based element access.
Definition: matrix_3d.hpp:174
bool operator==(const Matrix3D &matrix) const noexcept
Compares to an other matrix.
Definition: matrix_3d.hpp:216
Double precision 3x3 matrix class.
Definition: matrix_3d.hpp:58
Root namespace for the Image Manager interface.
Definition: version.hpp:11
Matrix3D() noexcept=default
Default constructor for empty matrix.
Matrix3D(double roll, double pitch, double yaw)
Creates a rotation matrix from the given Euler angles.
Definition: matrix_3d.hpp:102
double * operator[](int row) noexcept
Index based element access.
Definition: matrix_3d.hpp:150
AffineMatrix2D operator *(const AffineMatrix2D &lhs, const AffineMatrix2D &rhs) noexcept
Multiply two affine matrices.
Definition: affine_matrix_2d.hpp:245
Matrix3D & operator/=(const double &value) noexcept
Divides each element of this matrix by the given value.
Definition: matrix_3d.hpp:288
double Det() const
Matrix determinant.
Definition: matrix_3d.hpp:184
STL class.
const double & At(int row, int column) const noexcept
Index based element access.
Definition: matrix_3d.hpp:162
Matrix3D & operator *=(const Matrix3D &matrix)
Multiplies and assigns to this matrix.
Definition: matrix_3d.hpp:262
Matrix3D & operator -=(const Matrix3D &matrix) noexcept
Subtracts and assigns to this matrix.
Definition: matrix_3d.hpp:250
const double * operator[](int row) const noexcept
Index based element access.
Definition: matrix_3d.hpp:138
AffineMatrix2D operator-(const AffineMatrix2D &lhs, const AffineMatrix2D &rhs) noexcept
Subtract two affine matrices.
Definition: affine_matrix_2d.hpp:231
void Invert()
Inverts this matrix if possible.
Definition: matrix_3d.hpp:200