CVB++ 15.0
matrix_2d.hpp
1#pragma once
2
3#include "global.hpp"
4
5#include "angle.hpp"
6#include "point_2d.hpp"
7
8namespace Cvb
9{
10
11 CVB_BEGIN_INLINE_NS
13
15 class Matrix2D final
16 {
17 public:
19
23 static Matrix2D Identity() noexcept
24 {
25 return Matrix2D(1.0, 0.0, 0.0, 1.0);
26 }
27
29
32 Matrix2D() noexcept = default;
33
35
39 template <std::size_t N>
40 Matrix2D(const double (&list)[N]) noexcept // NOLINT
41 {
42 static_assert(N == 4, "CVB: Matrix2D must have 4 elements");
43 std::copy(std::begin(list), std::end(list), &a11_);
44 }
45
47
54 Matrix2D(double a11, double a12, double a21, double a22) noexcept
55 : a11_(a11)
56 , a12_(a12)
57 , a21_(a21)
58 , a22_(a22)
59 {
60 }
61
63
68 explicit Matrix2D(Angle rotation, double scale = 1.0) noexcept
69 {
70 a11_ = (scale * Cos(rotation)); // NOLINT(cppcoreguidelines-prefer-member-initializer)
71 a22_ = a11_; // NOLINT(cppcoreguidelines-prefer-member-initializer)
72 a21_ = scale * Sin(rotation); // NOLINT(cppcoreguidelines-prefer-member-initializer)
73 a12_ = -a21_; // NOLINT(cppcoreguidelines-prefer-member-initializer)
74 }
75
77
81 explicit Matrix2D(double scale) noexcept
82 : Matrix2D(scale, scale)
83 {
84 }
85
87
92 Matrix2D(double scaleX, double scaleY) noexcept
93 : Matrix2D(scaleX, 0.0, scaleY, 0.0)
94 {
95 }
96
98
104 : Matrix2D(column1.X(), column2.X(), column1.Y(), column2.Y())
105 {
106 }
107
109
114 const double *operator[](int row) const noexcept
115 {
116
117 return &((&a11_)[row << 1]);
118 }
119
121
126 double *operator[](int row) noexcept
127 {
128 return &((&a11_)[row << 1]);
129 }
130
132
138 const double &At(int row, int column) const noexcept
139 {
140 return (*this)[row][column];
141 }
142
144
150 double &At(int row, int column) noexcept
151 {
152 return (*this)[row][column];
153 }
154
156
160 double A11() const noexcept
161 {
162 return a11_;
163 }
164
166
170 void SetA11(double a11) noexcept
171 {
172 a11_ = a11;
173 }
174
176
180 double A12() const noexcept
181 {
182 return a12_;
183 }
184
186
190 void SetA12(double a12) noexcept
191 {
192 a12_ = a12;
193 }
194
196
200 double A21() const noexcept
201 {
202 return a21_;
203 }
204
206
210 void SetA21(double a21) noexcept
211 {
212 a21_ = a21;
213 }
214
216
220 double A22() const noexcept
221 {
222 return a22_;
223 }
224
226
230 void SetA22(double a22) noexcept
231 {
232 a22_ = a22;
233 }
234
236
240 double Det() const noexcept
241 {
242 return a11_ * a22_ - a21_ * a12_;
243 }
244
246
251 void Invert()
252 {
253 *this = Inverse();
254 }
255
257
264 {
265 if (std::fabs(Det()) < 1e-9)
266 throw std::invalid_argument("matrix is not invertible");
267
268 double det_1 = 1.0 / Det();
269 return Matrix2D(a22_ * det_1, -a12_ * det_1, -a21_ * det_1, a11_ * det_1);
270 }
271
273
278 bool operator==(const Matrix2D &matrix) const noexcept
279 {
280 return a11_ == matrix.a11_ && a12_ == matrix.a12_ && a21_ == matrix.a21_ && a22_ == matrix.a22_;
281 }
282
284
289 bool operator!=(const Matrix2D &matrix) const noexcept
290 {
291 return !(*this == matrix);
292 }
293
295
300 Matrix2D &operator+=(const Matrix2D &matrix) noexcept
301 {
302 a11_ += matrix.a11_;
303 a12_ += matrix.a12_;
304 a21_ += matrix.a21_;
305 a22_ += matrix.a22_;
306 return *this;
307 }
308
310
315 Matrix2D &operator-=(const Matrix2D &matrix) noexcept
316 {
317 a11_ -= matrix.a11_;
318 a12_ -= matrix.a12_;
319 a21_ -= matrix.a21_;
320 a22_ -= matrix.a22_;
321 return *this;
322 }
323
325
330 Matrix2D &operator*=(const Matrix2D &matrix) noexcept
331 {
332 *this = Matrix2D(a11_ * matrix.a11_ + a12_ * matrix.a21_, a11_ * matrix.a12_ + a12_ * matrix.a22_,
333 a21_ * matrix.a11_ + a22_ * matrix.a21_, a21_ * matrix.a12_ + a22_ * matrix.a22_);
334 return *this;
335 }
336
338
343 Matrix2D &operator*=(const double &value) noexcept
344 {
345 a11_ *= value;
346 a12_ *= value;
347 a21_ *= value;
348 a22_ *= value;
349 return *this;
350 }
351
353
358 Matrix2D &operator/=(const double &value) noexcept
359 {
360 a11_ /= value;
361 a12_ /= value;
362 a21_ /= value;
363 a22_ /= value;
364 return *this;
365 }
366
367 private:
368 double a11_ = 0.0;
369 double a12_ = 0.0;
370 double a21_ = 0.0;
371 double a22_ = 0.0;
372 };
373
375
383 inline Matrix2D operator+(const Matrix2D &lhs, const Matrix2D &rhs)
384 {
385 return Matrix2D(lhs.A11() + rhs.A11(), lhs.A12() + rhs.A12(), lhs.A21() + rhs.A21(), lhs.A22() + rhs.A22());
386 }
387
389
397 inline Matrix2D operator-(const Matrix2D &lhs, const Matrix2D &rhs)
398 {
399 return Matrix2D(lhs.A11() - rhs.A11(), lhs.A12() - rhs.A12(), lhs.A21() - rhs.A21(), lhs.A22() - rhs.A22());
400 }
401
403
411 inline Matrix2D operator*(const Matrix2D &lhs, const Matrix2D &rhs)
412 {
413 return Matrix2D(lhs.A11() * rhs.A11() + lhs.A12() * rhs.A21(), lhs.A11() * rhs.A12() + lhs.A12() * rhs.A22(),
414 lhs.A21() * rhs.A11() + lhs.A22() * rhs.A21(), lhs.A21() * rhs.A12() + lhs.A22() * rhs.A22());
415 }
416
418
426 inline Point2D<double> operator*(const Matrix2D &lhs, const Point2D<double> &rhs)
427 {
428 return Point2D<double>(lhs.A11() * rhs.X() + lhs.A12() * rhs.Y(), lhs.A21() * rhs.X() + lhs.A22() * rhs.Y());
429 }
430
432
440 inline Matrix2D operator*(const Matrix2D &lhs, const double &rhs)
441 {
442 return Matrix2D(lhs.A11() * rhs, lhs.A12() * rhs, lhs.A21() * rhs, lhs.A22() * rhs);
443 }
444
446
454 inline Matrix2D operator*(const double &lhs, const Matrix2D &rhs)
455 {
456 return rhs * lhs;
457 }
458
460
468 inline Matrix2D operator/(const Matrix2D &lhs, const double &rhs)
469 {
470 return Matrix2D(lhs.A11() / rhs, lhs.A12() / rhs, lhs.A21() / rhs, lhs.A22() / rhs);
471 }
472
473 CVB_END_INLINE_NS
474
475} // namespace Cvb
T begin(T... args)
Object for convenient and type - safe handling of angles.
Definition angle.hpp:16
const double & At(int row, int column) const noexcept
Index based element access.
Definition matrix_2d.hpp:138
Matrix2D(Cvb::Point2D< double > column1, Cvb::Point2D< double > column2) noexcept
Construct a 2x2 matrix from two column vectors.
Definition matrix_2d.hpp:103
Matrix2D operator+(const Matrix2D &lhs, const Matrix2D &rhs)
Add two matrices.
Definition matrix_2d.hpp:383
Matrix2D operator*(const double &lhs, const Matrix2D &rhs)
Multiply scalar with matrix .
Definition matrix_2d.hpp:454
Matrix2D operator*(const Matrix2D &lhs, const Matrix2D &rhs)
Multiply two matrices.
Definition matrix_2d.hpp:411
bool operator!=(const Matrix2D &matrix) const noexcept
Compares to an other matrix.
Definition matrix_2d.hpp:289
void SetA12(double a12) noexcept
Sets top right matrix element.
Definition matrix_2d.hpp:190
const double * operator[](int row) const noexcept
Index based element access.
Definition matrix_2d.hpp:114
double A11() const noexcept
Gets top left matrix element.
Definition matrix_2d.hpp:160
double * operator[](int row) noexcept
Index based element access.
Definition matrix_2d.hpp:126
Point2D< double > operator*(const Matrix2D &lhs, const Point2D< double > &rhs)
Multiply matrix with 2D point.
Definition matrix_2d.hpp:426
void SetA11(double a11) noexcept
Sets top left matrix element.
Definition matrix_2d.hpp:170
static Matrix2D Identity() noexcept
The identity element.
Definition matrix_2d.hpp:23
double A22() const noexcept
Gets bottom right matrix element.
Definition matrix_2d.hpp:220
Matrix2D operator/(const Matrix2D &lhs, const double &rhs)
Divide matrix by scalar.
Definition matrix_2d.hpp:468
Matrix2D & operator*=(const double &value) noexcept
Multiplies and assigns to this matrix.
Definition matrix_2d.hpp:343
Matrix2D operator-(const Matrix2D &lhs, const Matrix2D &rhs)
Substract two matrices.
Definition matrix_2d.hpp:397
double A12() const noexcept
Gets top right matrix element.
Definition matrix_2d.hpp:180
Matrix2D & operator-=(const Matrix2D &matrix) noexcept
Subtracts and assigns to this matrix.
Definition matrix_2d.hpp:315
double A21() const noexcept
Gets bottom left matrix element.
Definition matrix_2d.hpp:200
Matrix2D operator*(const Matrix2D &lhs, const double &rhs)
Multiply matrix with scalar.
Definition matrix_2d.hpp:440
Matrix2D(Angle rotation, double scale=1.0) noexcept
Construct a 2x2 matrix that is a combination of a rotation and scale operation.
Definition matrix_2d.hpp:68
bool operator==(const Matrix2D &matrix) const noexcept
Compares to an other matrix.
Definition matrix_2d.hpp:278
double Det() const noexcept
Matrix determinant.
Definition matrix_2d.hpp:240
Matrix2D & operator+=(const Matrix2D &matrix) noexcept
Adds and assigns to this matrix.
Definition matrix_2d.hpp:300
Matrix2D(double scaleX, double scaleY) noexcept
Constructs a 2x2 matrix that represent a scaling with different scaling in x and y directions.
Definition matrix_2d.hpp:92
Matrix2D & operator*=(const Matrix2D &matrix) noexcept
Multiplies and assigns to this matrix.
Definition matrix_2d.hpp:330
void Invert()
Inverts this matrix in-place if possible.
Definition matrix_2d.hpp:251
Matrix2D & operator/=(const double &value) noexcept
Divides each element of this matrix by the given value.
Definition matrix_2d.hpp:358
Matrix2D() noexcept=default
Default constructor for empty matrix.
double & At(int row, int column) noexcept
Index based element access.
Definition matrix_2d.hpp:150
void SetA22(double a22) noexcept
Sets bottom right matrix element.
Definition matrix_2d.hpp:230
Matrix2D(double a11, double a12, double a21, double a22) noexcept
Construct a 2x2 matrix.
Definition matrix_2d.hpp:54
Matrix2D(double scale) noexcept
Construct a 2x2 matrix that represents a scaling.
Definition matrix_2d.hpp:81
Matrix2D Inverse()
Gets the inverse of this matrix if possible.
Definition matrix_2d.hpp:263
void SetA21(double a21) noexcept
Sets bottom left matrix element.
Definition matrix_2d.hpp:210
Multi-purpose 2D vector class.
Definition point_2d.hpp:20
T X() const noexcept
Gets the x-component of the point.
Definition point_2d.hpp:84
T Y() const noexcept
Gets the y-component of the point.
Definition point_2d.hpp:104
T copy(T... args)
T end(T... args)
T fabs(T... args)
Root namespace for the Image Manager interface.
Definition c_bayer_to_rgb.h:17
double Sin(Angle angle) noexcept
Returns the sine of an angle.
Definition angle.hpp:429
double Cos(Angle angle) noexcept
Returns the cosine of an angle.
Definition angle.hpp:403