CVB++ 15.0
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#include "core_3d.hpp"
12
13namespace Cvb
14{
15
16CVB_BEGIN_INLINE_NS
17
18
19class Matrix3D;
20
21
23
31inline Matrix3D operator+(const Matrix3D & lhs, const Matrix3D & rhs);
32
34
42inline Matrix3D operator-(const Matrix3D & lhs, const Matrix3D & rhs);
43
44
46
54inline Matrix3D operator*(const Matrix3D & lhs, const Matrix3D & rhs);
55
57
59class Matrix3D final
60{
61 public:
62
64
68 static Matrix3D Identity() noexcept
69 {
70 return {{
71 1.0, 0.0, 0.0,
72 0.0, 1.0, 0.0,
73 0.0, 0.0, 1.0
74 }};
75 }
76
78
81 Matrix3D() noexcept = default;
82
84
88 template<std::size_t N>
89 Matrix3D(const double(&list)[N]) noexcept // NOLINT
90 {
91 static_assert(N == 9, "CVB: Matrix3D must have 9 elements");
92 std::copy(std::begin(list), std::end(list), matrix_.data()->data());
93 }
94
96
109 Matrix3D(double alpha, double beta, double gamma)
110 {
111 Internal::DoResCall([&]()
112 {
113 auto thisData = reinterpret_cast<CExports::CVC3DMatrix*>(this);
114 return CVB_CALL_CAPI(CVC3DRotationMatrixFromRotationAngles(alpha, beta, gamma, *thisData));
115 });
116 }
117
119
134 Matrix3D(double alpha, double beta, double gamma, Factors3D scale)
135 {
136 Internal::DoResCall([&]()
137 {
138 auto thisData = reinterpret_cast<CExports::CVC3DMatrix*>(this);
139 return CVB_CALL_CAPI(CVC3DMatrixFromRotationAnglesScale(alpha, beta, gamma, *reinterpret_cast<CExports::CVC3DFactors*>(&scale), *thisData));
140 });
141 }
142
144
163 bool TryGetRotationAngles(double& alpha, double& beta, double& gamma) const noexcept
164 {
165 auto thisData = reinterpret_cast<const CExports::CVC3DMatrix*>(this);
166 return CVB_CALL_CAPI(CVC3DRotationAnglesFromRotationMatrix(*thisData, alpha, beta, gamma)) == Cvb::CExports::CVC_ERROR_CODES::CVC_E_OK;
167 }
168
170
210 void RotationAnglesScale(double& alpha, double& beta, double& gamma, Factors3D &scale, double &precision) const
211 {
212 Internal::DoResCall([&]()
213 {
214 precision = -1.0;
215 auto thisData = reinterpret_cast<const CExports::CVC3DMatrix*>(this);
216 auto errcode = CVB_CALL_CAPI(CVC3DRotationAnglesScaleFromMatrix(*thisData, alpha, beta, gamma, *reinterpret_cast<CExports::CVC3DFactors*>(&scale)));
217
218 // if not a valid matrix, then estimate alpha, beta, gamma, scale
219 if (errcode< 0)
220 return CVB_CALL_CAPI(CVC3DRotationAnglesScaleFromMatrixApproximation(*thisData, alpha, beta, gamma, *reinterpret_cast<CExports::CVC3DFactors*>(&scale), precision));
221 else
222 return errcode;
223 });
224 }
225
227
243 void RollPitchYaw(double & roll, double & pitch, double & yaw) const
244 {
245 Internal::DoResCall([&]()
246 {
247 auto thisData = reinterpret_cast<const CExports::CVC3DMatrix*>(this);
248 return CVB_CALL_CAPI(CVC3DRollPitchYawFromRotationMatrix(*thisData, roll, pitch, yaw));
249 });
250
251 }
252
254
259 const double* operator[](int row) const noexcept
260 {
261 return matrix_[row].data(); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
262 }
263
264
266
271 double* operator[](int row) noexcept
272 {
273 return matrix_[row].data(); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
274 }
275
277
283 const double& At(int row, int column) const noexcept
284 {
285 return (*this)[row][column];
286 }
287
289
295 double& At(int row, int column) noexcept
296 {
297 return (*this)[row][column];
298 }
299
301
305 double Det() const
306 {
307 return Internal::DoResCallValueOut<double>([&](double & value)
308 {
309 auto thisData = reinterpret_cast<const CExports::CVC3DMatrix*>(this);
310 return CVB_CALL_CAPI(CVC3DMatrixDeterminant(*thisData, value));
311 });
312 }
313
314
316
321 void Invert()
322 {
323 Internal::DoResCall([&]()
324 {
325 auto data = reinterpret_cast<const CExports::CVC3DMatrix*>(this);
326 auto dataInv = reinterpret_cast<CExports::CVC3DMatrix*>(this);
327 return CVB_CALL_CAPI(CVC3DInvertMatrix(*data, *dataInv));
328 });
329 }
330
332
339 {
340 auto result = *this;
341 result.Invert();
342 return result;
343 }
344
346
351 bool operator==(const Matrix3D& matrix) const noexcept
352 {
353 return matrix_ == matrix.matrix_;
354 }
355
357
362 bool operator!=(const Matrix3D& matrix) const noexcept
363 {
364 return !(*this == matrix);
365 }
366
368
373 Matrix3D& operator +=(const Matrix3D & matrix) noexcept
374 {
375 *this = *this + matrix;
376 return *this;
377 }
378
380
385 Matrix3D& operator -=(const Matrix3D & matrix) noexcept
386 {
387 *this = *this - matrix;
388 return *this;
389 }
390
392
398 {
399 *this = *this * matrix;
400 return *this;
401 }
402
404
409 Matrix3D& operator *=(const double & value) noexcept
410 {
411 for (auto & line : matrix_)
412 for (auto & element : line)
413 element *= value;
414 return *this;
415 }
416
418
423 Matrix3D& operator /=(const double & value) noexcept
424 {
425 for(auto & line : matrix_)
426 for(auto & element : line)
427 element /= value;
428 return *this;
429 }
430
431
432
433 private:
434
435
437};
438
439
440
441
442inline Matrix3D operator+(const Matrix3D & lhs, const Matrix3D & rhs)
443{
444 return
445 {{
446 lhs[0][0] + rhs[0][0], lhs[0][1] + rhs[0][1], lhs[0][2] + rhs[0][2],
447 lhs[1][0] + rhs[1][0], lhs[1][1] + rhs[1][1], lhs[1][2] + rhs[1][2],
448 lhs[2][0] + rhs[2][0], lhs[2][1] + rhs[2][1], lhs[2][2] + rhs[2][2],
449 }};
450}
451
452
453inline Matrix3D operator-(const Matrix3D & lhs, const Matrix3D & rhs)
454{
455 return
456 { {
457 lhs[0][0] - rhs[0][0], lhs[0][1] - rhs[0][1], lhs[0][2] - rhs[0][2],
458 lhs[1][0] - rhs[1][0], lhs[1][1] - rhs[1][1], lhs[1][2] - rhs[1][2],
459 lhs[2][0] - rhs[2][0], lhs[2][1] - rhs[2][1], lhs[2][2] - rhs[2][2],
460 } };
461}
462
463
464inline Matrix3D operator*(const Matrix3D & lhs, const Matrix3D & rhs)
465{
466
467 return Internal::DoResCallValueOut<Matrix3D>([&](Matrix3D & value)
468 {
469 auto valueData = reinterpret_cast<CExports::CVC3DMatrix*>(&value);
470 auto lhsData = reinterpret_cast<const CExports::CVC3DMatrix*>(&lhs);
471 auto rhsData = reinterpret_cast<const CExports::CVC3DMatrix*>(&rhs);
472 return CVB_CALL_CAPI(CVC3DMultiplyMatrices(*lhsData,
473 *rhsData,
474 *valueData));
475 });
476
477}
478
480
488inline Point3D<double> operator*(const Matrix3D & lhs, const Point3D<double> & rhs)
489{
490 return
492 lhs[0][0] * rhs[0] + lhs[0][1] * rhs[1] + lhs[0][2] * rhs[2],
493 lhs[1][0] * rhs[0] + lhs[1][1] * rhs[1] + lhs[1][2] * rhs[2],
494 lhs[2][0] * rhs[0] + lhs[2][1] * rhs[1] + lhs[2][2] * rhs[2],
495 }};
496}
497
499
507inline Matrix3D operator*(const Matrix3D & lhs, const double & rhs)
508{
509 return
510 {{
511 lhs[0][0] * rhs, lhs[0][1] * rhs, lhs[0][2] * rhs,
512 lhs[1][0] * rhs, lhs[1][1] * rhs, lhs[1][2] * rhs,
513 lhs[2][0] * rhs, lhs[2][1] * rhs, lhs[2][2] * rhs
514 }};
515}
516
518
526inline Matrix3D operator*(const double & lhs, const Matrix3D & rhs)
527{
528 return rhs * lhs;
529}
530
532
540inline Matrix3D operator/(const Matrix3D & lhs, const double & rhs)
541{
542 return
543 {{
544 lhs[0][0] / rhs, lhs[0][1] / rhs, lhs[0][2] / rhs,
545 lhs[1][0] / rhs, lhs[1][1] / rhs, lhs[1][2] / rhs,
546 lhs[2][0] / rhs, lhs[2][1] / rhs, lhs[2][2] / rhs
547 }};
548}
549
550
551
552
553
554
555CVB_END_INLINE_NS
556
557}
Double precision 3x3 matrix class.
Definition: matrix_3d.hpp:60
const double & At(int row, int column) const noexcept
Index based element access.
Definition: matrix_3d.hpp:283
Matrix3D(double alpha, double beta, double gamma, Factors3D scale)
Creates a transformation matrix from the given Euler angles and scaling.
Definition: matrix_3d.hpp:134
bool operator!=(const Matrix3D &matrix) const noexcept
Compares to an other matrix.
Definition: matrix_3d.hpp:362
void RotationAnglesScale(double &alpha, double &beta, double &gamma, Factors3D &scale, double &precision) const
Computes the Euler angles and scaling from the matrix.
Definition: matrix_3d.hpp:210
Matrix3D & operator*=(const Matrix3D &matrix)
Multiplies and assigns to this matrix.
Definition: matrix_3d.hpp:397
const double * operator[](int row) const noexcept
Index based element access.
Definition: matrix_3d.hpp:259
Matrix3D Inverse()
Gets the inverse of this matrix if possible.
Definition: matrix_3d.hpp:338
bool operator==(const Matrix3D &matrix) const noexcept
Compares to an other matrix.
Definition: matrix_3d.hpp:351
bool TryGetRotationAngles(double &alpha, double &beta, double &gamma) const noexcept
Tries to compute the Euler angles from the matrix.
Definition: matrix_3d.hpp:163
double * operator[](int row) noexcept
Index based element access.
Definition: matrix_3d.hpp:271
void RollPitchYaw(double &roll, double &pitch, double &yaw) const
Computes the Euler angles Roll, Pitch and Yaw for this matrix.
Definition: matrix_3d.hpp:243
Matrix3D operator*(const double &lhs, const Matrix3D &rhs)
Multiply scalar with matrix .
Definition: matrix_3d.hpp:526
Matrix3D() noexcept=default
Default constructor for empty matrix.
Matrix3D & operator/=(const double &value) noexcept
Divides each element of this matrix by the given value.
Definition: matrix_3d.hpp:423
double Det() const
Matrix determinant.
Definition: matrix_3d.hpp:305
Matrix3D & operator-=(const Matrix3D &matrix) noexcept
Subtracts and assigns to this matrix.
Definition: matrix_3d.hpp:385
Matrix3D(double alpha, double beta, double gamma)
Creates a rotation matrix from the given Euler angles.
Definition: matrix_3d.hpp:109
Matrix3D operator/(const Matrix3D &lhs, const double &rhs)
Divide matrix by scalar.
Definition: matrix_3d.hpp:540
Point3D< double > operator*(const Matrix3D &lhs, const Point3D< double > &rhs)
Multiply matrix with 3D point.
Definition: matrix_3d.hpp:488
void Invert()
Inverts this matrix in-place if possible.
Definition: matrix_3d.hpp:321
Matrix3D & operator+=(const Matrix3D &matrix) noexcept
Adds and assigns to this matrix.
Definition: matrix_3d.hpp:373
static Matrix3D Identity() noexcept
The identity element.
Definition: matrix_3d.hpp:68
double & At(int row, int column) noexcept
Index based element access.
Definition: matrix_3d.hpp:295
Matrix3D operator*(const Matrix3D &lhs, const double &rhs)
Multiply matrix with scalar.
Definition: matrix_3d.hpp:507
@ CVC_E_OK
No Error occurred.
Definition: CVCError.h:58
Root namespace for the Image Manager interface.
Definition: c_barcode.h:24
AffineMatrix2D operator+(const AffineMatrix2D &lhs, const AffineMatrix2D &rhs) noexcept
Add two affine matrices.
Definition: affine_matrix_2d.hpp:231
AffineMatrix2D operator*(const AffineMatrix2D &lhs, const AffineMatrix2D &rhs) noexcept
Multiply two affine matrices.
Definition: affine_matrix_2d.hpp:259
AffineMatrix2D operator-(const AffineMatrix2D &lhs, const AffineMatrix2D &rhs) noexcept
Subtract two affine matrices.
Definition: affine_matrix_2d.hpp:245
Factor components to be applied in the 3D domain.
Definition: core_3d.hpp:17