CVB++ 15.0
matrix_3d.hpp
1#pragma once
2
3#include "_cexports/c_core_3d.h"
4
5#include "global.hpp"
6
7#include "point_3d.hpp"
8#include "core_3d.hpp"
9
10namespace Cvb
11{
12
13 CVB_BEGIN_INLINE_NS
14
15 class Matrix3D;
16
18
26 inline Matrix3D operator+(const Matrix3D &lhs, const Matrix3D &rhs);
27
29
37 inline Matrix3D operator-(const Matrix3D &lhs, const Matrix3D &rhs);
38
40
48 inline Matrix3D operator*(const Matrix3D &lhs, const Matrix3D &rhs);
49
51
53 class Matrix3D final
54 {
55 public:
57
61 static Matrix3D Identity() noexcept
62 {
63 return {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}};
64 }
65
67
70 Matrix3D() noexcept = default;
71
73
77 template <std::size_t N>
78 Matrix3D(const double (&list)[N]) noexcept // NOLINT
79 {
80 static_assert(N == 9, "CVB: Matrix3D must have 9 elements");
81 std::copy(std::begin(list), std::end(list), matrix_.data()->data());
82 }
83
85
98 Matrix3D(double alpha, double beta, double gamma)
99 {
100 Internal::DoResCall([&]() {
101 auto thisData = reinterpret_cast<CExports::CVC3DMatrix *>(this);
102 return CVB_CALL_CAPI(CVC3DRotationMatrixFromRotationAngles(alpha, beta, gamma, *thisData));
103 });
104 }
105
107
122 Matrix3D(double alpha, double beta, double gamma, Factors3D scale)
123 {
124 Internal::DoResCall([&]() {
125 auto thisData = reinterpret_cast<CExports::CVC3DMatrix *>(this);
126 return CVB_CALL_CAPI(CVC3DMatrixFromRotationAnglesScale(
127 alpha, beta, gamma, *reinterpret_cast<CExports::CVC3DFactors *>(&scale), *thisData));
128 });
129 }
130
132
151 bool TryGetRotationAngles(double &alpha, double &beta, double &gamma) const noexcept
152 {
153 auto thisData = reinterpret_cast<const CExports::CVC3DMatrix *>(this);
154 return CVB_CALL_CAPI(CVC3DRotationAnglesFromRotationMatrix(*thisData, alpha, beta, gamma))
155 == Cvb::CExports::CVC_ERROR_CODES::CVC_E_OK;
156 }
157
159
199 void RotationAnglesScale(double &alpha, double &beta, double &gamma, Factors3D &scale, double &precision) const
200 {
201 Internal::DoResCall([&]() {
202 precision = -1.0;
203 auto thisData = reinterpret_cast<const CExports::CVC3DMatrix *>(this);
204 auto errcode = CVB_CALL_CAPI(CVC3DRotationAnglesScaleFromMatrix(
205 *thisData, alpha, beta, gamma, *reinterpret_cast<CExports::CVC3DFactors *>(&scale)));
206
207 // if not a valid matrix, then estimate alpha, beta, gamma, scale
208 if (errcode < 0)
209 return CVB_CALL_CAPI(CVC3DRotationAnglesScaleFromMatrixApproximation(
210 *thisData, alpha, beta, gamma, *reinterpret_cast<CExports::CVC3DFactors *>(&scale), precision));
211 else
212 return errcode;
213 });
214 }
215
217
234 void RollPitchYaw(double &roll, double &pitch, double &yaw) const
235 {
236 Internal::DoResCall([&]() {
237 auto thisData = reinterpret_cast<const CExports::CVC3DMatrix *>(this);
238 return CVB_CALL_CAPI(CVC3DRollPitchYawFromRotationMatrix(*thisData, roll, pitch, yaw));
239 });
240 }
241
243
248 const double *operator[](int row) const noexcept
249 {
250 return matrix_[row].data(); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
251 }
252
254
259 double *operator[](int row) noexcept
260 {
261 return matrix_[row].data(); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
262 }
263
265
271 const double &At(int row, int column) const noexcept
272 {
273 return (*this)[row][column];
274 }
275
277
283 double &At(int row, int column) noexcept
284 {
285 return (*this)[row][column];
286 }
287
289
293 double Det() const
294 {
295 return Internal::DoResCallValueOut<double>([&](double &value) {
296 auto thisData = reinterpret_cast<const CExports::CVC3DMatrix *>(this);
297 return CVB_CALL_CAPI(CVC3DMatrixDeterminant(*thisData, value));
298 });
299 }
300
302
307 void Invert()
308 {
309 Internal::DoResCall([&]() {
310 auto data = reinterpret_cast<const CExports::CVC3DMatrix *>(this);
311 auto dataInv = reinterpret_cast<CExports::CVC3DMatrix *>(this);
312 return CVB_CALL_CAPI(CVC3DInvertMatrix(*data, *dataInv));
313 });
314 }
315
317
324 {
325 auto result = *this;
326 result.Invert();
327 return result;
328 }
329
331
336 bool operator==(const Matrix3D &matrix) const noexcept
337 {
338 return matrix_ == matrix.matrix_;
339 }
340
342
347 bool operator!=(const Matrix3D &matrix) const noexcept
348 {
349 return !(*this == matrix);
350 }
351
353
358 Matrix3D &operator+=(const Matrix3D &matrix) noexcept
359 {
360 *this = *this + matrix;
361 return *this;
362 }
363
365
370 Matrix3D &operator-=(const Matrix3D &matrix) noexcept
371 {
372 *this = *this - matrix;
373 return *this;
374 }
375
377
383 {
384 *this = *this * matrix;
385 return *this;
386 }
387
389
394 Matrix3D &operator*=(const double &value) noexcept
395 {
396 for (auto &line : matrix_)
397 for (auto &element : line)
398 element *= value;
399 return *this;
400 }
401
403
408 Matrix3D &operator/=(const double &value) noexcept
409 {
410 for (auto &line : matrix_)
411 for (auto &element : line)
412 element /= value;
413 return *this;
414 }
415
416 private:
418 };
419
420 inline Matrix3D operator+(const Matrix3D &lhs, const Matrix3D &rhs)
421 {
422 return {{
423 lhs[0][0] + rhs[0][0],
424 lhs[0][1] + rhs[0][1],
425 lhs[0][2] + rhs[0][2],
426 lhs[1][0] + rhs[1][0],
427 lhs[1][1] + rhs[1][1],
428 lhs[1][2] + rhs[1][2],
429 lhs[2][0] + rhs[2][0],
430 lhs[2][1] + rhs[2][1],
431 lhs[2][2] + rhs[2][2],
432 }};
433 }
434
435 inline Matrix3D operator-(const Matrix3D &lhs, const Matrix3D &rhs)
436 {
437 return {{
438 lhs[0][0] - rhs[0][0],
439 lhs[0][1] - rhs[0][1],
440 lhs[0][2] - rhs[0][2],
441 lhs[1][0] - rhs[1][0],
442 lhs[1][1] - rhs[1][1],
443 lhs[1][2] - rhs[1][2],
444 lhs[2][0] - rhs[2][0],
445 lhs[2][1] - rhs[2][1],
446 lhs[2][2] - rhs[2][2],
447 }};
448 }
449
450 inline Matrix3D operator*(const Matrix3D &lhs, const Matrix3D &rhs)
451 {
452
453 return Internal::DoResCallValueOut<Matrix3D>([&](Matrix3D &value) {
454 auto valueData = reinterpret_cast<CExports::CVC3DMatrix *>(&value);
455 auto lhsData = reinterpret_cast<const CExports::CVC3DMatrix *>(&lhs);
456 auto rhsData = reinterpret_cast<const CExports::CVC3DMatrix *>(&rhs);
457 return CVB_CALL_CAPI(CVC3DMultiplyMatrices(*lhsData, *rhsData, *valueData));
458 });
459 }
460
462
470 inline Point3D<double> operator*(const Matrix3D &lhs, const Point3D<double> &rhs)
471 {
472 return Point3D<double>{{
473 lhs[0][0] * rhs[0] + lhs[0][1] * rhs[1] + lhs[0][2] * rhs[2],
474 lhs[1][0] * rhs[0] + lhs[1][1] * rhs[1] + lhs[1][2] * rhs[2],
475 lhs[2][0] * rhs[0] + lhs[2][1] * rhs[1] + lhs[2][2] * rhs[2],
476 }};
477 }
478
480
488 inline Matrix3D operator*(const Matrix3D &lhs, const double &rhs)
489 {
490 return {{lhs[0][0] * rhs, lhs[0][1] * rhs, lhs[0][2] * rhs, lhs[1][0] * rhs, lhs[1][1] * rhs, lhs[1][2] * rhs,
491 lhs[2][0] * rhs, lhs[2][1] * rhs, lhs[2][2] * rhs}};
492 }
493
495
503 inline Matrix3D operator*(const double &lhs, const Matrix3D &rhs)
504 {
505 return rhs * lhs;
506 }
507
509
517 inline Matrix3D operator/(const Matrix3D &lhs, const double &rhs)
518 {
519 return {{lhs[0][0] / rhs, lhs[0][1] / rhs, lhs[0][2] / rhs, lhs[1][0] / rhs, lhs[1][1] / rhs, lhs[1][2] / rhs,
520 lhs[2][0] / rhs, lhs[2][1] / rhs, lhs[2][2] / rhs}};
521 }
522
523 CVB_END_INLINE_NS
524
525} // namespace Cvb
T begin(T... args)
Double precision 3x3 matrix class.
Definition matrix_3d.hpp:54
const double & At(int row, int column) const noexcept
Index based element access.
Definition matrix_3d.hpp:271
Matrix3D(double alpha, double beta, double gamma, Factors3D scale)
Creates a transformation matrix from the given Euler angles and scaling.
Definition matrix_3d.hpp:122
bool operator!=(const Matrix3D &matrix) const noexcept
Compares to an other matrix.
Definition matrix_3d.hpp:347
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:199
Matrix3D & operator*=(const Matrix3D &matrix)
Multiplies and assigns to this matrix.
Definition matrix_3d.hpp:382
const double * operator[](int row) const noexcept
Index based element access.
Definition matrix_3d.hpp:248
Matrix3D Inverse()
Gets the inverse of this matrix if possible.
Definition matrix_3d.hpp:323
bool operator==(const Matrix3D &matrix) const noexcept
Compares to an other matrix.
Definition matrix_3d.hpp:336
bool TryGetRotationAngles(double &alpha, double &beta, double &gamma) const noexcept
Tries to compute the Euler angles from the matrix.
Definition matrix_3d.hpp:151
double * operator[](int row) noexcept
Index based element access.
Definition matrix_3d.hpp:259
void RollPitchYaw(double &roll, double &pitch, double &yaw) const
Computes the Euler angles Roll, Pitch and Yaw for this matrix.
Definition matrix_3d.hpp:234
Matrix3D operator*(const double &lhs, const Matrix3D &rhs)
Multiply scalar with matrix .
Definition matrix_3d.hpp:503
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:408
double Det() const
Matrix determinant.
Definition matrix_3d.hpp:293
Matrix3D & operator-=(const Matrix3D &matrix) noexcept
Subtracts and assigns to this matrix.
Definition matrix_3d.hpp:370
Matrix3D(double alpha, double beta, double gamma)
Creates a rotation matrix from the given Euler angles.
Definition matrix_3d.hpp:98
Matrix3D operator/(const Matrix3D &lhs, const double &rhs)
Divide matrix by scalar.
Definition matrix_3d.hpp:517
Point3D< double > operator*(const Matrix3D &lhs, const Point3D< double > &rhs)
Multiply matrix with 3D point.
Definition matrix_3d.hpp:470
void Invert()
Inverts this matrix in-place if possible.
Definition matrix_3d.hpp:307
Matrix3D & operator+=(const Matrix3D &matrix) noexcept
Adds and assigns to this matrix.
Definition matrix_3d.hpp:358
static Matrix3D Identity() noexcept
The identity element.
Definition matrix_3d.hpp:61
Matrix3D & operator*=(const double &value) noexcept
Multiplies and assigns to this matrix.
Definition matrix_3d.hpp:394
double & At(int row, int column) noexcept
Index based element access.
Definition matrix_3d.hpp:283
Matrix3D operator*(const Matrix3D &lhs, const double &rhs)
Multiply matrix with scalar.
Definition matrix_3d.hpp:488
Multi-purpose 3D vector class.
Definition point_3d.hpp:22
T copy(T... args)
T end(T... args)
Root namespace for the Image Manager interface.
Definition c_bayer_to_rgb.h:17
AffineMatrix2D operator+(const AffineMatrix2D &lhs, const AffineMatrix2D &rhs) noexcept
Add two affine matrices.
Definition affine_matrix_2d.hpp:223
AffineMatrix2D operator*(const AffineMatrix2D &lhs, const AffineMatrix2D &rhs) noexcept
Multiply two affine matrices.
Definition affine_matrix_2d.hpp:251
AffineMatrix2D operator-(const AffineMatrix2D &lhs, const AffineMatrix2D &rhs) noexcept
Subtract two affine matrices.
Definition affine_matrix_2d.hpp:237
Factor components to be applied in the 3D domain.
Definition core_3d.hpp:16