NAVTOR SDK  v.3.0
Software Development Kit for fast and efficient development of ECDIS, ECS and generic marine applications
matrix3x2.h
Go to the documentation of this file.
1 #ifndef SDK_MATRIX_3X2_H_
11 #define SDK_MATRIX_3X2_H_
12 
13 #define _USE_MATH_DEFINES
14 #include <cmath>
15 #include <float.h>
16 #include <base/inc/base_types.h>
18 #include "math_const.h"
19 #include "matrix_base_types.h"
20 #include "matrix3x3.h"
21 
22 namespace sdk {
23 
26 template <class _SDKMatrix3X2>
27 class Matrix3X2T : public _SDKMatrix3X2
28 {
30 public:
31  typedef _SDKMatrix3X2 SDKMatrix3X2;
32  typedef typename SDKMatrix3X2::coordinate_type coordinate_type;
33  Matrix3X2T() noexcept
34  {
35  SetIdentity();
36  }
37  Matrix3X2T(const SDKMatrix3X2& m) noexcept
38  : SDKMatrix3X2(m)
39  {
40  }
41  Matrix3X2T(const double s11, const double s12,
42  const double s21, const double s22,
43  const double s31, const double s32) noexcept
44  {
45  this->_11 = coordinate_type(s11); this->_12 = coordinate_type(s12);
46  this->_21 = coordinate_type(s21); this->_22 = coordinate_type(s22);
47  this->_31 = coordinate_type(s31); this->_32 = coordinate_type(s32);
48  }
49 
51  void SetIdentity() noexcept
52  {
53  this->_11 = this->_22 = 1;
54  this->_12 = this->_21 = this->_31 = this->_32 = 0;
55  }
56 
58  bool IsIdentity() const noexcept
59  {
60  if (this->_11 != 1 || this->_22 != 1
61  || this->_12 != 0 || this->_21 != 0 || this->_31 != 0 || this->_32 != 0)
62  return false;
63  return true;
64  }
65 
69  const _MyType& Rotate(double angle_deg, const SDKPointF2D& center) noexcept
70  {
71  double angle_rad = (angle_deg / 180.0) * kPI;
72  using std::sin;
73  using std::cos;
74  double s = sin(angle_rad);
75  double c = cos(angle_rad);
76 
77  this->_11 = coordinate_type(c);
78  this->_12 = coordinate_type(s);
79  this->_21 = coordinate_type(-s);
80  this->_22 = coordinate_type(c);
81  this->_31 = coordinate_type(-center.x * (c - 1) + center.y * s);
82  this->_32 = coordinate_type(-center.y * (c - 1) - center.x * s);
83 
84  return *this;
85  }
86 
88  const _MyType& Translate(const float& x, const float& y) noexcept
89  {
90  this->_11 = 1; this->_12 = 0;
91  this->_21 = 0; this->_22 = 1;
92  this->_31 = x; this->_32 = y;
93 
94  return *this;
95  }
96 
98  const _MyType& Scale(const float& scale_x, const float& scale_y) noexcept
99  {
100  this->_11 = scale_x; this->_12 = 0.0;
101  this->_21 = 0.0; this->_22 = scale_y;
102  this->_31 = 0.0; this->_32 = 0.0;
103 
104  return *this;
105  }
106 
107  // NOTE: It's a fake multiplication function, it's impossible to
108  // multiply 3X2 matrix to 3X2 matrix, only 3X2 to 2X3
109  // But for geometric operations each of 3X2 matrixes can be converted to 3X3
110  // and multiplied
111  static _MyType Multiply(const SDKMatrix3X2& m1, const SDKMatrix3X2& m2)
112  {
114  CMatrix3X3 m1_(m1); // Last column will be 0.0, 0.0, 1.0
115  CMatrix3X3 m2_(m2); // Last column will be 0.0, 0.0, 1.0
116  CMatrix3X3 res = CMatrix3X3::Multiply(m1_, m2_);
117  return _MyType(res._11, res._12, res._21, res._22, res._31, res._32);
118  }
119 
120  _MyType& operator=(const SDKMatrix3X2& m) noexcept
121  {
122  *static_cast<SDKMatrix3X2*>(this) = m;
123  return *this;
124  }
125 
126  const SDKMatrix3X2& get() const noexcept
127  {
128  return *static_cast<const SDKMatrix3X2*>(this);
129  }
130 
131  // Transforms a point according to this matrix.
132  // / a b 0 \ / a * x + c * y + tx \ T
133  // (x y 1) * | c d 0 | = | b * x + d * y + ty |
134  // \ tx ty 1 / \ 1 /
135  SDKPointD2D Transform(const SDKPointD2D& point) const {
136  SDKPointD2D res;
137  res.x = this->_11 * point.x + this->_21 * point.y + this->_31;
138  res.y = this->_12 * point.x + this->_22 * point.y + this->_32;
139  return res;
140  }
141  SDKPointF2D Transform(const SDKPointF2D& point) const {
142  SDKPointD2D point_d = {point.x, point.y};
143  SDKPointD2D res_d = Transform(point_d);
144  SDKPointF2D res;
145  res.x = static_cast<float>(res_d.x);
146  res.y = static_cast<float>(res_d.y);
147  return res;
148  }
149  SDKPointI2D Transform(const SDKPointI2D& point) const {
150  SDKPointD2D point_d = { static_cast<double>(point.x),
151  static_cast<double>(point.y) };
152  SDKPointD2D res_d = Transform(point_d);
153  SDKPointI2D res;
154  res.x = RoundToNearest<SDKInt32, double>(res_d.x);
155  res.y = RoundToNearest<SDKInt32, double>(res_d.y);
156  return res;
157  }
158  SDKRectD2D Transform(const SDKRectD2D& rect) const {
159  SDKPointD2D pt_sw = { rect.x, rect.y };
160  SDKPointD2D pt_nw = { rect.x, rect.y + rect.height };
161  SDKPointD2D pt_se = { rect.x + rect.width, rect.y };
162  SDKPointD2D pt_ne = { rect.x + rect.width,
163  rect.y + rect.height };
164  pt_sw = Transform(pt_sw);
165  pt_nw = Transform(pt_nw);
166  pt_se = Transform(pt_se);
167  pt_ne = Transform(pt_ne);
168  double min_x = min4dbl(pt_sw.x, pt_nw.x, pt_se.x, pt_ne.x);
169  double min_y = min4dbl(pt_sw.y, pt_nw.y, pt_se.y, pt_ne.y);
170  double max_x = max4dbl(pt_sw.x, pt_nw.x, pt_se.x, pt_ne.x);
171  double max_y = max4dbl(pt_sw.y, pt_nw.y, pt_se.y, pt_ne.y);
172  SDKRectD2D res = { min_x, min_y, max_x - min_x, max_y - min_y };
173  return res;
174  }
175  SDKRectF2D Transform(const SDKRectF2D& rect) const {
176  SDKRectD2D rect_d = { rect.x, rect.y, rect.width, rect.height };
177  SDKRectD2D res_d = Transform(rect_d);
178  SDKRectF2D res = { static_cast<float>(res_d.x), static_cast<float>(res_d.y),
179  static_cast<float>(res_d.width), static_cast<float>(res_d.height) };
180  return res;
181  }
182  SDKRectI2D Transform(const SDKRectI2D& rect) const {
183  SDKRectD2D rect_d = { static_cast<double>(rect.x),
184  static_cast<double>(rect.y),
185  static_cast<double>(rect.width),
186  static_cast<double>(rect.height) };
187  SDKRectD2D res_d = Transform(rect_d);
188  SDKRect2D res = { RoundToNearest<SDKInt32>(res_d.x),
189  RoundToNearest<SDKInt32>(res_d.y),
190  RoundToNearest<SDKUInt32>(res_d.width),
191  RoundToNearest<SDKUInt32>(res_d.height) };
192  return res;
193  }
194 
195 };
196 
197 typedef Matrix3X2T<SDKMatrix3X2> Matrix3X2, CMatrix3X2;
198 typedef Matrix3X2T<SDKMatrixD3X2> MatrixD3X2, CMatrixD3X2;
199 typedef Matrix3X2T<SDKMatrixF3X2> MatrixF3X2, CMatrixF3X2;
200 } // namespace sdk
201 
202 #endif // SDK_MATRIX_3X2_H_
matrix3x3.h
Matrix 3X3 implementation.
base_types.h
SDK base types.
sdk::Matrix3X2T::SetIdentity
void SetIdentity() noexcept
Sets the matrix to an identity.
Definition: matrix3x2.h:51
sdk::Matrix3X3T::Multiply
_MyType & Multiply(const SDKMatrix3X3 &m2) noexcept
Multiplication of matrices.
Definition: matrix3x3.h:263
SDKRectD2D
2D Rectangle
Definition: geometry_base_types.h:1356
sdk::Matrix3X2T::Rotate
const _MyType & Rotate(double angle_deg, const SDKPointF2D &center) noexcept
Rotate around specified point on specified angle. Negative angle - clockwise rotation in SDK coordina...
Definition: matrix3x2.h:69
SDKRectF2D
2D Rectangle
Definition: geometry_base_types.h:1295
SDKRectI2D
2D Rectangle
Definition: geometry_base_types.h:1417
SDKPointF2D
Single 2D point.
Definition: geometry_base_types.h:33
matrix_base_types.h
Matrix base definitions.
sdk::Matrix3X2T::IsIdentity
bool IsIdentity() const noexcept
Checks the matrix identity.
Definition: matrix3x2.h:58
geometry_base_types.h
Geometry base types.
sdk::Matrix3X3T
Includes member functions to manipulate SDKMatrix3X3 structure.
Definition: matrix3x3.h:25
SDKPointI2D
Single 2D point.
Definition: geometry_base_types.h:178
sdk::Matrix3X2T::Translate
const _MyType & Translate(const float &x, const float &y) noexcept
Creates a translation transformation that has the specified x and y displacements.
Definition: matrix3x2.h:88
sdk::Matrix3X2T
Matrix3X2T class.
Definition: matrix3x2.h:27
kPI
#define kPI
PI.
Definition: math_const.h:16
sdk::Matrix3X2T::Scale
const _MyType & Scale(const float &scale_x, const float &scale_y) noexcept
Creates the scale transformation matrix.
Definition: matrix3x2.h:98
math_const.h
Math constants definition.
SDKPointD2D
A two dimensional point.
Definition: geometry_base_types.h:242