Sen API
Sen Libraries
Loading...
Searching...
No Matches
mat3.h
Go to the documentation of this file.
1// === mat3.h ==========================================================================================================
2// Sen Infrastructure
3// Released under the Apache License v2.0 (SPDX-License-Identifier Apache-2.0).
4// See the LICENSE.txt file for more information.
5// © Airbus SAS, Airbus Helicopters, and Airbus Defence and Space SAU/GmbH/SAS.
6// =====================================================================================================================
7
8#ifndef SEN_LIBS_SRC_DR_MAT3_H
9#define SEN_LIBS_SRC_DR_MAT3_H
10
11#include "quat.h"
12#include "vec3.h"
13
14// sen
17
18// std
19#include <cmath>
20#include <initializer_list>
21
22// NOLINTNEXTLINE
23#define INNER_PRODUCT(a, b, r, c) \
24 ((a).v_[r][0] * (b).v_[0][c]) + ((a).v_[r][1] * (b).v_[1][c]) + ((a).v_[r][2] * (b).v_[2][c])
25
26// NOLINTNEXTLINE
27#define SET_ROW(row, v1, v2, v3) \
28 v_[(row)][0] = (v1); \
29 v_[(row)][1] = (v2); \
30 v_[(row)][2] = (v3);
31// @}
32
33namespace sen::util
34{
35
37template <typename T>
38class Mat3
39{
40public:
41 SEN_COPY_MOVE(Mat3)
42
43public:
44 Mat3() = default;
45 ~Mat3() = default;
46
48 Mat3(std::initializer_list<std::initializer_list<T>> list);
49
50public:
53
55 static Mat3 makeFromEulerYPB(const Vec3d& eulerAngles);
56
58 static Mat3 makeTransposedFromEulerYPB(const Vec3d& eulerAngles);
59
61 static Mat3 makeOmegaOmegaTranspose(const Vec3d& omega);
62
64 static Mat3 makeSkewMatrix(const Vec3d& omega);
65
66public: // access operators
68 T& operator()(u32 row, u32 col);
69
71 T operator()(u32 row, u32 col) const;
72
73public:
75 void transpose(const Mat3& value);
76
78 void mult(const Mat3& lhs, const Mat3& rhs);
79
81 void preMult(const Mat3& other);
82
84 void postMult(const Mat3& other);
85
87 [[nodiscard]] Vec3<T> preMult(const Vec3<T>& vec) const noexcept;
88
90 [[nodiscard]] Vec3<T> postMult(const Vec3<T>& vec) const noexcept;
91
92public: // multiplication operators
94 [[nodiscard]] Vec3<T> operator*(const Vec3<T>& vec) const noexcept;
95
97 Mat3 operator*(const Mat3& other) const noexcept;
98
100 Mat3 operator*(T scalar) const noexcept;
101
103 Mat3 operator+(const Mat3& other) const noexcept;
104
105private:
106 T v_[3U][3U];
107};
108
111
112//-------------------------------------------------------------------------------------------------------------------
113// Inline implementation
114//-------------------------------------------------------------------------------------------------------------------
115
116template <typename T>
117Mat3<T>::Mat3(std::initializer_list<std::initializer_list<T>> list)
118{
119 u32 i = 0;
120 u32 j = 0;
121 for (const auto& row: list)
122 {
123 for (const auto& elem: row)
124 {
125 v_[i][j++] = elem; // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
126 if (j == 3)
127 {
128 j = 0;
129 i++;
130 }
131 if (i == 3)
132 {
133 return;
134 }
135 }
136 }
137}
138
139template <typename T>
141{
142 return {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
143}
144
145template <typename T>
147{
148 const auto psi = eulerAngles.getX();
149 const auto theta = eulerAngles.getY();
150 const auto phi = eulerAngles.getZ();
151
152 const auto cosPsi = cos(psi);
153 const auto cosTheta = cos(theta);
154 const auto cosPhi = cos(phi);
155 const auto sinPsi = sin(psi);
156 const auto sinTheta = sin(theta);
157 const auto sinPhi = sin(phi);
158 const auto sinPhiTimesSinTheta = sinPhi * sinTheta;
159 const auto cosPhiTimesSinTheta = cosPhi * sinTheta;
160
161 Mat3<T> result {};
162 {
163 result(0, 0) = cosTheta * cosPsi;
164 result(0, 1) = cosTheta * sinPsi;
165 result(0, 2) = -sinTheta;
166 result(1, 0) = sinPhiTimesSinTheta * cosPsi - cosPhi * sinPsi;
167 result(1, 1) = sinPhiTimesSinTheta * sinPsi + cosPhi * cosPsi;
168 result(1, 2) = sinPhi * cosTheta;
169 result(2, 0) = cosPhiTimesSinTheta * cosPsi + sinPhi * sinPsi;
170 result(2, 1) = cosPhiTimesSinTheta * sinPsi - sinPhi * cosPsi;
171 result(2, 2) = cosPhi * cosTheta;
172 }
173
174 return result;
175}
176
177template <typename T>
179{
180 const auto psi = eulerAngles.getX();
181 const auto theta = eulerAngles.getY();
182 const auto phi = eulerAngles.getZ();
183
184 const auto cosPsi = cos(psi);
185 const auto cosTheta = cos(theta);
186 const auto cosPhi = cos(phi);
187 const auto sinPsi = sin(psi);
188 const auto sinTheta = sin(theta);
189 const auto sinPhi = sin(phi);
190 const auto sinPhiTimesSinTheta = sinPhi * sinTheta;
191 const auto cosPhiTimesSinTheta = cosPhi * sinTheta;
192
193 Mat3<T> result {};
194 {
195 result(0, 0) = cosTheta * cosPsi;
196 result(1, 0) = cosTheta * sinPsi;
197 result(2, 0) = -sinTheta;
198 result(0, 1) = sinPhiTimesSinTheta * cosPsi - cosPhi * sinPsi;
199 result(1, 1) = sinPhiTimesSinTheta * sinPsi + cosPhi * cosPsi;
200 result(2, 1) = sinPhi * cosTheta;
201 result(0, 2) = cosPhiTimesSinTheta * cosPsi + sinPhi * sinPsi;
202 result(1, 2) = cosPhiTimesSinTheta * sinPsi - sinPhi * cosPsi;
203 result(2, 2) = cosPhi * cosTheta;
204 }
205
206 return result;
207}
208
209template <typename T>
211{
212 const auto wx = omega.getX();
213 const auto wy = omega.getY();
214 const auto wz = omega.getZ();
215 const auto wxwy = wx * wy;
216 const auto wxwz = wx * wz;
217 const auto wywz = wy * wz;
218
219 Mat3<T> result {};
220 {
221 result(0, 0) = wx * wx;
222 result(0, 1) = wxwy;
223 result(0, 2) = wxwz;
224 result(1, 0) = wxwy;
225 result(1, 1) = wy * wy;
226 result(1, 2) = wywz;
227 result(2, 0) = wxwz;
228 result(2, 1) = wywz;
229 result(2, 2) = wz * wz;
230 }
231
232 return result;
233}
234
235template <typename T>
237{
238 const auto wx = omega.getX();
239 const auto wy = omega.getY();
240 const auto wz = omega.getZ();
241
242 Mat3<T> result {};
243 {
244 result(0, 0) = 0;
245 result(0, 1) = -wz;
246 result(0, 2) = wy;
247 result(1, 0) = wz;
248 result(1, 1) = 0;
249 result(1, 2) = -wx;
250 result(2, 0) = -wy;
251 result(2, 1) = wx;
252 result(2, 2) = 0;
253 }
254 return result;
255}
256
257template <typename T>
258inline T& Mat3<T>::operator()(u32 row, u32 col)
259{
260 return v_[row][col]; // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
261}
262
263template <typename T>
264inline T Mat3<T>::operator()(u32 row, u32 col) const
265{
266 return v_[row][col]; // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
267}
268
269template <typename T>
270inline void Mat3<T>::transpose(const Mat3& value)
271{
272 if (&value == this)
273 {
274 Mat3 tm(value);
275 return transpose(tm);
276 }
277 v_[0][0] = value.v_[0][0];
278 v_[0][1] = value.v_[1][0];
279 v_[0][2] = value.v_[2][0];
280 v_[1][0] = value.v_[0][1];
281 v_[1][1] = value.v_[1][1];
282 v_[1][2] = value.v_[2][1];
283 v_[2][0] = value.v_[0][2];
284 v_[2][1] = value.v_[1][2];
285 v_[2][2] = value.v_[2][2];
286}
287
288template <typename T>
289inline void Mat3<T>::mult(const Mat3& lhs, const Mat3& rhs)
290{
291 if (&lhs == this)
292 {
293 postMult(rhs);
294 return;
295 }
296 if (&rhs == this)
297 {
298 preMult(lhs);
299 return;
300 }
301
302 v_[0][0] = INNER_PRODUCT(lhs, rhs, 0, 0);
303 v_[0][1] = INNER_PRODUCT(lhs, rhs, 0, 1);
304 v_[0][2] = INNER_PRODUCT(lhs, rhs, 0, 2);
305 v_[1][0] = INNER_PRODUCT(lhs, rhs, 1, 0);
306 v_[1][1] = INNER_PRODUCT(lhs, rhs, 1, 1);
307 v_[1][2] = INNER_PRODUCT(lhs, rhs, 1, 2);
308 v_[2][0] = INNER_PRODUCT(lhs, rhs, 2, 0);
309 v_[2][1] = INNER_PRODUCT(lhs, rhs, 2, 1);
310 v_[2][2] = INNER_PRODUCT(lhs, rhs, 2, 2);
311}
312
313template <typename T>
314inline void Mat3<T>::preMult(const Mat3& other)
315{
316 // temporal storage used for efficiency
317 T temp[3];
318
319 for (u32 col = 0; col < 3U; ++col)
320 {
321 temp[0] = INNER_PRODUCT(other, *this, 0, col); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
322 temp[1] = INNER_PRODUCT(other, *this, 1, col); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
323 temp[2] = INNER_PRODUCT(other, *this, 2, col); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
324 v_[0][col] = temp[0]; // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
325 v_[1][col] = temp[1]; // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
326 v_[2][col] = temp[2]; // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
327 }
328}
329
330template <typename T>
331inline void Mat3<T>::postMult(const Mat3& other)
332{
333 // temporal storage used for efficiency
334 T temp[3];
335
336 for (u32 row = 0; row < 3U; ++row)
337 {
338 temp[0] = INNER_PRODUCT(*this, other, row, 0); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
339 temp[1] = INNER_PRODUCT(*this, other, row, 1); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
340 temp[2] = INNER_PRODUCT(*this, other, row, 2); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
341 SET_ROW(row, temp[0], temp[1], temp[2]) // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
342 }
343}
344
345template <typename T>
346Vec3<T> Mat3<T>::preMult(const Vec3<T>& vec) const noexcept
347{
348 return {
349 v_[0][0] * vec.getX() + v_[1][0] * vec.getY() + v_[2][0] * vec.getZ(),
350 v_[0][1] * vec.getX() + v_[1][1] * vec.getY() + v_[2][1] * vec.getZ(),
351 v_[0][2] * vec.getX() + v_[1][2] * vec.getY() + v_[2][2] * vec.getZ(),
352 };
353}
354
355template <typename T>
356inline Vec3<T> Mat3<T>::postMult(const Vec3<T>& vec) const noexcept
357{
358 return {v_[0][0] * vec.getX() + v_[0][1] * vec.getY() + v_[0][2] * vec.getZ(),
359 v_[1][0] * vec.getX() + v_[1][1] * vec.getY() + v_[1][2] * vec.getZ(),
360 v_[2][0] * vec.getX() + v_[2][1] * vec.getY() + v_[2][2] * vec.getZ()};
361}
362
363template <typename T>
364inline Vec3<T> Mat3<T>::operator*(const Vec3<T>& vec) const noexcept
365{
366 return postMult(vec);
367}
368
369template <typename T>
370inline Mat3<T> Mat3<T>::operator*(const Mat3& other) const noexcept
371{
372 Mat3<T> result {};
373 result.mult(*this, other);
374 return result;
375}
376
377template <typename T>
378inline Mat3<T> Mat3<T>::operator*(T scalar) const noexcept
379{
380 Mat3<T> result {};
381
382 for (u32 i = 0; i < 3U; ++i)
383 {
384 for (u32 j = 0; j < 3U; ++j)
385 {
386 result(i, j) = v_[i][j] * scalar; // NOLINT
387 }
388 }
389 return result;
390}
391
392template <typename T>
393inline Mat3<T> Mat3<T>::operator+(const Mat3& other) const noexcept
394{
395 Mat3<T> result {};
396
397 for (u32 i = 0; i < 3U; ++i)
398 {
399 for (u32 j = 0; j < 3U; ++j)
400 {
401 result(i, j) = v_[i][j] + other(i, j); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
402 }
403 }
404 return result;
405}
406
407} // namespace sen::util
408
409#endif // SEN_LIBS_SRC_DR_MAT3_H
Handles all mathematical ops involving 3D Matrices.
Definition mat3.h:39
Mat3 operator*(const Mat3 &other) const noexcept
Operator for post-multiplying the matrix by another matrix.
Definition mat3.h:370
T & operator()(u32 row, u32 col)
Allows read/write access to the elements of the matrix.
Definition mat3.h:258
~Mat3()=default
T operator()(u32 row, u32 col) const
Allows read-only access to the elements of the matrix.
Definition mat3.h:264
static Mat3 makeOmegaOmegaTranspose(const Vec3d &omega)
Returns the matrix generated when multiplying the angular velocity vector by its transpose.
Definition mat3.h:210
void preMult(const Mat3 &other)
Pre-multiplies the matrix given as argument to the current instance.
Definition mat3.h:314
Mat3 operator*(T scalar) const noexcept
Operator for multiplying the matrix by a constant.
Definition mat3.h:378
void mult(const Mat3 &lhs, const Mat3 &rhs)
Performs a matrix multiplication and stores the result in the current instance.
Definition mat3.h:289
void transpose(const Mat3 &value)
Transforms a matrix into its transpose.
Definition mat3.h:270
static Mat3 makeIdentity()
Constructs an identity matrix.
Definition mat3.h:140
Mat3()=default
void postMult(const Mat3 &other)
Post-multiplies the matrix given as argument to the current instance.
Definition mat3.h:331
static Mat3 makeFromEulerYPB(const Vec3d &eulerAngles)
Returns the world to body transformation matrix given the Euler angles.
Definition mat3.h:146
Vec3< T > operator*(const Vec3< T > &vec) const noexcept
Operator for post-multiplying the matrix by a vector.
Definition mat3.h:364
Vec3< T > postMult(const Vec3< T > &vec) const noexcept
Post-multiplies the vector given as argument to the current instance.
Definition mat3.h:356
static Mat3 makeSkewMatrix(const Vec3d &omega)
Returns the skew matrix given an angular velocity.
Definition mat3.h:236
static Mat3 makeTransposedFromEulerYPB(const Vec3d &eulerAngles)
Returns the world to body transformation matrix given the Euler angles.
Definition mat3.h:178
Mat3 operator+(const Mat3 &other) const noexcept
Operator for summing the matrix with another matrix.
Definition mat3.h:393
Mat3(std::initializer_list< std::initializer_list< T > > list)
Initializer list constructor.
Definition mat3.h:117
Vec3< T > preMult(const Vec3< T > &vec) const noexcept
Pre-multiplies the vector given as argument to the current instance.
Definition mat3.h:346
Handles all mathematical ops involving 3D Vectors.
Definition vec3.h:24
T getY() const noexcept
Definition vec3.h:190
T getX() const noexcept
Definition vec3.h:184
T getZ() const noexcept
Definition vec3.h:196
uint32_t u32
Definition numbers.h:25
#define SET_ROW(row, v1, v2, v3)
Definition mat3.h:27
#define INNER_PRODUCT(a, b, r, c)
Definition mat3.h:23
Definition iterator_adapters.h:16
Mat3< f32 > Mat3f
Definition mat3.h:109
Mat3< f64 > Mat3d
Definition mat3.h:110
Vec3< f64 > Vec3d
Definition vec3.h:115