CVB++ 14.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
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
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 Matrix2D(Angle rotation, double scale = 1.0) noexcept
70 {
71 a11_ = (scale * Cos(rotation));
72 a22_ = a11_;
73 a21_ = scale * Sin(rotation);
74 a12_ = -a21_;
75 }
76
77
79
83 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 double det_1 = 1.0 / Det();
260 *this = Matrix2D(a22_ * det_1, -a12_ * det_1, -a21_ * det_1, a11_ * det_1);
261 }
262
264
269 bool operator==(const Matrix2D& matrix) const noexcept
270 {
271 return a11_ == matrix.a11_
272 && a12_ == matrix.a12_
273 && a21_ == matrix.a21_
274 && a22_ == matrix.a22_;
275 }
276
278
283 bool operator!=(const Matrix2D& matrix) const noexcept
284 {
285 return !(*this == matrix);
286 }
287
289
294 Matrix2D& operator +=(const Matrix2D & matrix) noexcept
295 {
296 a11_ += matrix.a11_;
297 a12_ += matrix.a12_;
298 a21_ += matrix.a21_;
299 a22_ += matrix.a22_;
300 return *this;
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 *this = Matrix2D(a11_ * matrix.a11_ + a12_ * matrix.a21_,
327 a11_ * matrix.a12_ + a12_ * matrix.a22_,
328 a21_ * matrix.a11_ + a22_ * matrix.a21_,
329 a21_ * matrix.a12_ + a22_ * matrix.a22_);
330 return *this;
331 }
332
334
339 Matrix2D& operator *=(const double & value) noexcept
340 {
341 a11_ *= value;
342 a12_ *= value;
343 a21_ *= value;
344 a22_ *= value;
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
363
364
365 private:
366
367 double a11_ = 0.0;
368 double a12_ = 0.0;
369 double a21_ = 0.0;
370 double a22_ = 0.0;
371};
372
373
374
376
384inline Matrix2D operator+(const Matrix2D & lhs, const Matrix2D & rhs)
385{
386 return Matrix2D(lhs.A11() + rhs.A11(), lhs.A12() + rhs.A12(), lhs.A21() + rhs.A21(), lhs.A22() + rhs.A22());
387}
388
390
398inline Matrix2D operator-(const Matrix2D & lhs, const Matrix2D & rhs)
399{
400 return Matrix2D(lhs.A11() - rhs.A11(), lhs.A12() - rhs.A12(), lhs.A21() - rhs.A21(), lhs.A22() - rhs.A22());
401}
402
404
412inline Matrix2D operator*(const Matrix2D & lhs, const Matrix2D & rhs)
413{
414 return Matrix2D(lhs.A11() * rhs.A11() + lhs.A12() * rhs.A21(),
415 lhs.A11() * rhs.A12() + lhs.A12() * rhs.A22(),
416 lhs.A21() * rhs.A11() + lhs.A22() * rhs.A21(),
417 lhs.A21() * rhs.A12() + lhs.A22() * rhs.A22());
418}
419
421
429inline Point2D<double> operator*(const Matrix2D & lhs, const Point2D<double> & rhs)
430{
431 return Point2D<double>(lhs.A11() * rhs.X() + lhs.A12() * rhs.Y(), lhs.A21() * rhs.X() + lhs.A22() * rhs.Y());
432}
433
435
443inline Matrix2D operator*(const Matrix2D & lhs, const double & rhs)
444{
445 return Matrix2D(lhs.A11() * rhs, lhs.A12() * rhs, lhs.A21() * rhs, lhs.A22() * rhs);
446}
447
449
457inline Matrix2D operator*(const double & lhs, const Matrix2D & rhs)
458{
459 return rhs * lhs;
460}
461
463
471inline Matrix2D operator/(const Matrix2D & lhs, const double & rhs)
472{
473 return Matrix2D(lhs.A11() / rhs, lhs.A12() / rhs, lhs.A21() / rhs, lhs.A22() / rhs);
474}
475
476
477
478
479
480
481CVB_END_INLINE_NS
482
483}
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:384
Matrix2D operator*(const double &lhs, const Matrix2D &rhs)
Multiply scalar with matrix .
Definition: matrix_2d.hpp:457
Matrix2D operator*(const Matrix2D &lhs, const Matrix2D &rhs)
Multiply two matrices.
Definition: matrix_2d.hpp:412
bool operator!=(const Matrix2D &matrix) const noexcept
Compares to an other matrix.
Definition: matrix_2d.hpp:283
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:429
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:471
Matrix2D operator-(const Matrix2D &lhs, const Matrix2D &rhs)
Substract two matrices.
Definition: matrix_2d.hpp:398
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:309
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:443
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:269
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:294
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:324
void Invert()
Inverts this matrix 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:354
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
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