CVB++ 14.1
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
11CVB_BEGIN_INLINE_NS
13
15class Matrix2D final
16{
17 public:
18
20
24 static Matrix2D Identity() noexcept
25 {
26 return Matrix2D(1.0, 0.0, 0.0, 1.0);
27 }
28
30
33 Matrix2D() noexcept = default;
34
36
40 template<std::size_t N>
41 Matrix2D(const double(&list)[N]) noexcept // NOLINT
42 {
43 static_assert(N == 4, "CVB: Matrix2D must have 4 elements");
44 std::copy(std::begin(list), std::end(list), &a11_);
45 }
46
48
55 Matrix2D(double a11, double a12, double a21, double a22) noexcept
56 : a11_(a11)
57 , a12_(a12)
58 , a21_(a21)
59 , a22_(a22)
60 {
61 }
62
64
69 explicit Matrix2D(Angle rotation, double scale = 1.0) noexcept
70 {
71 a11_ = (scale * Cos(rotation)); // NOLINT(cppcoreguidelines-prefer-member-initializer)
72 a22_ = a11_; // NOLINT(cppcoreguidelines-prefer-member-initializer)
73 a21_ = scale * Sin(rotation); // NOLINT(cppcoreguidelines-prefer-member-initializer)
74 a12_ = -a21_; // NOLINT(cppcoreguidelines-prefer-member-initializer)
75 }
76
77
79
83 explicit Matrix2D(double scale) noexcept
84 : Matrix2D(scale, scale)
85 {
86 }
87
89
94 Matrix2D(double scaleX, double scaleY) noexcept
95 : Matrix2D(scaleX, 0.0, scaleY, 0.0)
96 {
97 }
98
100
106 : Matrix2D(column1.X(), column2.X(), column1.Y(), column2.Y())
107 {
108 }
109
110
112
117 const double* operator[](int row) const noexcept
118 {
119
120 return &((&a11_)[row << 1]);
121 }
122
124
129 double* operator[](int row) noexcept
130 {
131 return &((&a11_)[row << 1]);
132 }
133
134
136
142 const double& At(int row, int column) const noexcept
143 {
144 return (*this)[row][column];
145 }
146
148
154 double& At(int row, int column) noexcept
155 {
156 return (*this)[row][column];
157 }
158
159
161
165 double A11() const noexcept
166 {
167 return a11_;
168 }
169
171
175 void SetA11(double a11) noexcept
176 {
177 a11_ = a11;
178 }
179
181
185 double A12() const noexcept
186 {
187 return a12_;
188 }
189
191
195 void SetA12(double a12) noexcept
196 {
197 a12_ = a12;
198 }
199
201
205 double A21() const noexcept
206 {
207 return a21_;
208 }
209
211
215 void SetA21(double a21) noexcept
216 {
217 a21_ = a21;
218 }
219
221
225 double A22() const noexcept
226 {
227 return a22_;
228 }
229
231
235 void SetA22(double a22) noexcept
236 {
237 a22_ = a22;
238 }
239
241
245 double Det() const noexcept
246 {
247 return a11_ * a22_ - a21_ * a12_;
248 }
249
250
252
257 void Invert()
258 {
259 *this = Inverse();
260 }
261
263
270 {
271 if (std::fabs(Det()) < 1e-9)
272 throw std::invalid_argument("matrix is not invertible");
273
274 double det_1 = 1.0 / Det();
275 return Matrix2D(a22_ * det_1, -a12_ * det_1, -a21_ * det_1, a11_ * det_1);
276 }
277
279
284 bool operator==(const Matrix2D& matrix) const noexcept
285 {
286 return a11_ == matrix.a11_
287 && a12_ == matrix.a12_
288 && a21_ == matrix.a21_
289 && a22_ == matrix.a22_;
290 }
291
293
298 bool operator!=(const Matrix2D& matrix) const noexcept
299 {
300 return !(*this == matrix);
301 }
302
304
309 Matrix2D& operator +=(const Matrix2D & matrix) noexcept
310 {
311 a11_ += matrix.a11_;
312 a12_ += matrix.a12_;
313 a21_ += matrix.a21_;
314 a22_ += matrix.a22_;
315 return *this;
316 }
317
319
324 Matrix2D& operator -=(const Matrix2D & matrix) noexcept
325 {
326 a11_ -= matrix.a11_;
327 a12_ -= matrix.a12_;
328 a21_ -= matrix.a21_;
329 a22_ -= matrix.a22_;
330 return *this;
331 }
332
334
339 Matrix2D& operator *=(const Matrix2D & matrix) noexcept
340 {
341 *this = Matrix2D(a11_ * matrix.a11_ + a12_ * matrix.a21_,
342 a11_ * matrix.a12_ + a12_ * matrix.a22_,
343 a21_ * matrix.a11_ + a22_ * matrix.a21_,
344 a21_ * matrix.a12_ + a22_ * matrix.a22_);
345 return *this;
346 }
347
349
354 Matrix2D& operator *=(const double & value) noexcept
355 {
356 a11_ *= value;
357 a12_ *= value;
358 a21_ *= value;
359 a22_ *= value;
360 return *this;
361 }
362
364
369 Matrix2D& operator /=(const double & value) noexcept
370 {
371 a11_ /= value;
372 a12_ /= value;
373 a21_ /= value;
374 a22_ /= value;
375 return *this;
376 }
377
378
379
380 private:
381
382 double a11_ = 0.0;
383 double a12_ = 0.0;
384 double a21_ = 0.0;
385 double a22_ = 0.0;
386};
387
388
389
391
399inline Matrix2D operator+(const Matrix2D & lhs, const Matrix2D & rhs)
400{
401 return Matrix2D(lhs.A11() + rhs.A11(), lhs.A12() + rhs.A12(), lhs.A21() + rhs.A21(), lhs.A22() + rhs.A22());
402}
403
405
413inline Matrix2D operator-(const Matrix2D & lhs, const Matrix2D & rhs)
414{
415 return Matrix2D(lhs.A11() - rhs.A11(), lhs.A12() - rhs.A12(), lhs.A21() - rhs.A21(), lhs.A22() - rhs.A22());
416}
417
419
427inline Matrix2D operator*(const Matrix2D & lhs, const Matrix2D & rhs)
428{
429 return Matrix2D(lhs.A11() * rhs.A11() + lhs.A12() * rhs.A21(),
430 lhs.A11() * rhs.A12() + lhs.A12() * rhs.A22(),
431 lhs.A21() * rhs.A11() + lhs.A22() * rhs.A21(),
432 lhs.A21() * rhs.A12() + lhs.A22() * rhs.A22());
433}
434
436
444inline Point2D<double> operator*(const Matrix2D & lhs, const Point2D<double> & rhs)
445{
446 return Point2D<double>(lhs.A11() * rhs.X() + lhs.A12() * rhs.Y(), lhs.A21() * rhs.X() + lhs.A22() * rhs.Y());
447}
448
450
458inline Matrix2D operator*(const Matrix2D & lhs, const double & rhs)
459{
460 return Matrix2D(lhs.A11() * rhs, lhs.A12() * rhs, lhs.A21() * rhs, lhs.A22() * rhs);
461}
462
464
472inline Matrix2D operator*(const double & lhs, const Matrix2D & rhs)
473{
474 return rhs * lhs;
475}
476
478
486inline Matrix2D operator/(const Matrix2D & lhs, const double & rhs)
487{
488 return Matrix2D(lhs.A11() / rhs, lhs.A12() / rhs, lhs.A21() / rhs, lhs.A22() / rhs);
489}
490
491
492
493
494
495
496CVB_END_INLINE_NS
497
498}
Object for convenient and type - safe handling of angles.
Definition: angle.hpp:19
Double precision 2x2 matrix class.
Definition: matrix_2d.hpp:16
const double & At(int row, int column) const noexcept
Index based element access.
Definition: matrix_2d.hpp:142
Matrix2D(Cvb::Point2D< double > column1, Cvb::Point2D< double > column2) noexcept
Construct a 2x2 matrix from two column vectors.
Definition: matrix_2d.hpp:105
Matrix2D operator+(const Matrix2D &lhs, const Matrix2D &rhs)
Add two matrices.
Definition: matrix_2d.hpp:399
Matrix2D operator*(const double &lhs, const Matrix2D &rhs)
Multiply scalar with matrix .
Definition: matrix_2d.hpp:472
Matrix2D operator*(const Matrix2D &lhs, const Matrix2D &rhs)
Multiply two matrices.
Definition: matrix_2d.hpp:427
bool operator!=(const Matrix2D &matrix) const noexcept
Compares to an other matrix.
Definition: matrix_2d.hpp:298
void SetA12(double a12) noexcept
Sets top right matrix element.
Definition: matrix_2d.hpp:195
const double * operator[](int row) const noexcept
Index based element access.
Definition: matrix_2d.hpp:117
double A11() const noexcept
Gets top left matrix element.
Definition: matrix_2d.hpp:165
double * operator[](int row) noexcept
Index based element access.
Definition: matrix_2d.hpp:129
Point2D< double > operator*(const Matrix2D &lhs, const Point2D< double > &rhs)
Multiply matrix with 2D point.
Definition: matrix_2d.hpp:444
void SetA11(double a11) noexcept
Sets top left matrix element.
Definition: matrix_2d.hpp:175
static Matrix2D Identity() noexcept
The identity element.
Definition: matrix_2d.hpp:24
double A22() const noexcept
Gets bottom right matrix element.
Definition: matrix_2d.hpp:225
Matrix2D operator/(const Matrix2D &lhs, const double &rhs)
Divide matrix by scalar.
Definition: matrix_2d.hpp:486
Matrix2D operator-(const Matrix2D &lhs, const Matrix2D &rhs)
Substract two matrices.
Definition: matrix_2d.hpp:413
double A12() const noexcept
Gets top right matrix element.
Definition: matrix_2d.hpp:185
Matrix2D & operator-=(const Matrix2D &matrix) noexcept
Subtracts and assigns to this matrix.
Definition: matrix_2d.hpp:324
double A21() const noexcept
Gets bottom left matrix element.
Definition: matrix_2d.hpp:205
Matrix2D operator*(const Matrix2D &lhs, const double &rhs)
Multiply matrix with scalar.
Definition: matrix_2d.hpp:458
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:69
bool operator==(const Matrix2D &matrix) const noexcept
Compares to an other matrix.
Definition: matrix_2d.hpp:284
double Det() const noexcept
Matrix determinant.
Definition: matrix_2d.hpp:245
Matrix2D & operator+=(const Matrix2D &matrix) noexcept
Adds and assigns to this matrix.
Definition: matrix_2d.hpp:309
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:94
Matrix2D & operator*=(const Matrix2D &matrix) noexcept
Multiplies and assigns to this matrix.
Definition: matrix_2d.hpp:339
void Invert()
Inverts this matrix in-place if possible.
Definition: matrix_2d.hpp:257
Matrix2D & operator/=(const double &value) noexcept
Divides each element of this matrix by the given value.
Definition: matrix_2d.hpp:369
Matrix2D() noexcept=default
Default constructor for empty matrix.
double & At(int row, int column) noexcept
Index based element access.
Definition: matrix_2d.hpp:154
void SetA22(double a22) noexcept
Sets bottom right matrix element.
Definition: matrix_2d.hpp:235
Matrix2D(double a11, double a12, double a21, double a22) noexcept
Construct a 2x2 matrix.
Definition: matrix_2d.hpp:55
Matrix2D(double scale) noexcept
Construct a 2x2 matrix that represents a scaling.
Definition: matrix_2d.hpp:83
Matrix2D Inverse()
Gets the inverse of this matrix if possible.
Definition: matrix_2d.hpp:269
void SetA21(double a21) noexcept
Sets bottom left matrix element.
Definition: matrix_2d.hpp:215
T X() const noexcept
Gets the x-component of the point.
Definition: point_2d.hpp:86
T Y() const noexcept
Gets the y-component of the point.
Definition: point_2d.hpp:106
Root namespace for the Image Manager interface.
Definition: c_barcode.h:24
double Sin(Angle angle) noexcept
Returns the sine of an angle.
Definition: angle.hpp:438
double Cos(Angle angle) noexcept
Returns the cosine of an angle.
Definition: angle.hpp:411