matrix_2d.hpp
1 #pragma once
2 
3 #include "global.hpp"
4 
5 #include "angle.hpp"
6 #include "point_2d.hpp"
7 
8 namespace Cvb
9 {
10 
11 CVB_BEGIN_INLINE_NS
13 
15 class 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 
384 inline 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 
398 inline 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 
412 inline 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 
429 inline 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 
443 inline 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 
457 inline Matrix2D operator*(const double & lhs, const Matrix2D & rhs)
458 {
459  return rhs * lhs;
460 }
461 
463 
471 inline 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 
481 CVB_END_INLINE_NS
482 
483 }
Matrix2D & operator *=(const double &value) noexcept
Multiplies and assigns to this matrix.
Definition: matrix_2d.hpp:339
void SetA12(double a12) noexcept
Sets top right matrix element.
Definition: matrix_2d.hpp:195
double * operator[](int row) noexcept
Index based element access.
Definition: matrix_2d.hpp:129
double Cos(Angle angle) noexcept
Returns the cosine of an angle.
Definition: angle.hpp:411
Matrix2D & operator -=(const Matrix2D &matrix) noexcept
Subtracts and assigns to this matrix.
Definition: matrix_2d.hpp:309
void SetA11(double a11) noexcept
Sets top left matrix element.
Definition: matrix_2d.hpp:175
double A21() const noexcept
Gets bottom left matrix element.
Definition: matrix_2d.hpp:205
const double * operator[](int row) const noexcept
Index based element access.
Definition: matrix_2d.hpp:117
AffineMatrix2D operator+(const AffineMatrix2D &lhs, const AffineMatrix2D &rhs) noexcept
Add two affine matrices.
Definition: affine_matrix_2d.hpp:217
Matrix2D(double a11, double a12, double a21, double a22) noexcept
Construct a 2x2 matrix.
Definition: matrix_2d.hpp:55
static Matrix2D Identity() noexcept
The identity element.
Definition: matrix_2d.hpp:24
AffineMatrix2D operator/(const AffineMatrix2D &lhs, const double &rhs)
Divide affine matrix by scalar.
Definition: affine_matrix_2d.hpp:301
double Sin(Angle angle) noexcept
Returns the sine of an angle.
Definition: angle.hpp:438
Double precision 2x2 matrix class.
Definition: matrix_2d.hpp:15
Matrix2D(Cvb::Point2D< double > column1, Cvb::Point2D< double > column2) noexcept
Construct a 2x2 matrix from two column vectors.
Definition: matrix_2d.hpp:105
bool operator!=(const Matrix2D &matrix) const noexcept
Compares to an other matrix.
Definition: matrix_2d.hpp:283
double & At(int row, int column) noexcept
Index based element access.
Definition: matrix_2d.hpp:154
double Det() const noexcept
Matrix determinant.
Definition: matrix_2d.hpp:245
Root namespace for the Image Manager interface.
Definition: version.hpp:11
const double & At(int row, int column) const noexcept
Index based element access.
Definition: matrix_2d.hpp:142
bool operator==(const Matrix2D &matrix) const noexcept
Compares to an other matrix.
Definition: matrix_2d.hpp:269
T Y() const noexcept
Gets the y-component of the point.
Definition: point_2d.hpp:106
void SetA21(double a21) noexcept
Sets bottom left matrix element.
Definition: matrix_2d.hpp:215
Matrix2D & operator/=(const double &value) noexcept
Divides each element of this matrix by the given value.
Definition: matrix_2d.hpp:354
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
AffineMatrix2D operator *(const AffineMatrix2D &lhs, const AffineMatrix2D &rhs) noexcept
Multiply two affine matrices.
Definition: affine_matrix_2d.hpp:245
Matrix2D & operator+=(const Matrix2D &matrix) noexcept
Adds and assigns to this matrix.
Definition: matrix_2d.hpp:294
void SetA22(double a22) noexcept
Sets bottom right matrix element.
Definition: matrix_2d.hpp:235
T X() const noexcept
Gets the x-component of the point.
Definition: point_2d.hpp:86
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
void Invert()
Inverts this matrix if possible.
Definition: matrix_2d.hpp:257
double A22() const noexcept
Gets bottom right matrix element.
Definition: matrix_2d.hpp:225
Matrix2D() noexcept=default
Default constructor for empty matrix.
Matrix2D & operator *=(const Matrix2D &matrix) noexcept
Multiplies and assigns to this matrix.
Definition: matrix_2d.hpp:324
double A11() const noexcept
Gets top left matrix element.
Definition: matrix_2d.hpp:165
Matrix2D(double scale) noexcept
Construct a 2x2 matrix that represents a scaling.
Definition: matrix_2d.hpp:83
double A12() const noexcept
Gets top right matrix element.
Definition: matrix_2d.hpp:185
AffineMatrix2D operator-(const AffineMatrix2D &lhs, const AffineMatrix2D &rhs) noexcept
Subtract two affine matrices.
Definition: affine_matrix_2d.hpp:231
Object for convenient and type - safe handling of angles.
Definition: angle.hpp:18