Ocean
Loading...
Searching...
No Matches
Euler.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8#ifndef META_OCEAN_MATH_EULER_H
9#define META_OCEAN_MATH_EULER_H
10
11#include "ocean/math/Math.h"
12#include "ocean/math/Numeric.h"
13#include "ocean/math/Rotation.h"
15
16namespace Ocean
17{
18
19// Forward declaration
20template <typename T> class HomogenousMatrixT4;
21// Forward declaration
22template <typename T> class RotationT;
23// Forward declaration
24template <typename T> class QuaternionT;
25// Forward declaration
26template <typename T> class SquareMatrixT3;
27
28// Forward declaration.
29template <typename T> class EulerT;
30
31/**
32 * Definition of the Euler object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION either with single or double precision float data type.
33 * @see EulerT
34 * @ingroup math
35 */
37
38/**
39 * Instantiation of the EulerT template class using a double precision float data type.
40 * @see EulerT
41 * @ingroup math
42 */
44
45/**
46 * Instantiation of the EulerT template class using a single precision float data type.
47 * @see EulerT
48 * @ingroup math
49 */
51
52/**
53 * Definition of a typename alias for vectors with EulerT objects.
54 * @see EulerT
55 * @ingroup math
56 */
57template <typename T>
58using EulersT = std::vector<EulerT<T>>;
59
60/**
61 * Definition of a vector holding euler objects.
62 * @see Euler
63 * @ingroup math
64 */
65typedef std::vector<Euler> Eulers;
66
67/**
68 * This class implements an euler rotation with angles: yaw, pitch and roll.
69 * The yaw angle is defined about the positive y-axis with range [-Pi, Pi].<br>
70 * The pitch angle is defined about the positive x-axis with range [-Pi/2, Pi/2].<br>
71 * The roll angle is defined about the positive z-axis with range [-Pi, Pi].<br>
72 * The entire rotation can be written as matrix product: Ry(yaw) * Rx(pitch) * Rz(roll).<br>
73 * All angles are defined in radian.
74 * @tparam T Data type of angle values_
75 * @see Euler, EulerF, EulerD, Rotation, Quaternion, SquareMatrix3, ExponentialMap.
76 * @ingroup math
77 */
78template <typename T>
79class EulerT
80{
81 public:
82
83 /**
84 * Definition of the used data type.
85 */
86 typedef T Type;
87
88 public:
89
90 /**
91 * Creates a new Euler rotation with all angles zero.
92 */
93 EulerT();
94
95 /**
96 * Creates a new euler rotation by given angles.
97 * @param yaw The yaw angle with range [-Pi, Pi]
98 * @param pitch The pitch angle with range [-Pi/2, Pi/2]
99 * @param roll The roll angle with range [-Pi, Pi]
100 */
101 EulerT(const T yaw, const T pitch, const T roll);
102
103 /**
104 * Creates a new euler rotation by an array of angles.
105 * @param arrayValue Array with three angles, with order yaw, pitch, roll, must be valid
106 */
107 explicit EulerT(const T* arrayValue);
108
109 /**
110 * Creates a new euler rotation by a given homogeneous transformation.
111 * @param transformation The homogeneous transformation to create a euler rotation from
112 */
113 explicit EulerT(const HomogenousMatrixT4<T>& transformation);
114
115 /**
116 * Creates a new euler rotation by a given angle-axis rotation.
117 * @param rotation Angle-axis rotation to create a euler rotation from
118 */
119 explicit EulerT(const RotationT<T>& rotation);
120
121 /**
122 * Creates a new euler rotation by a given quaternion rotation.
123 * @param quaternion The quaternion rotation to create a euler rotation from
124 */
125 explicit EulerT(const QuaternionT<T>& quaternion);
126
127 /**
128 * Creates a new euler rotation by a given 3x3 matrix rotation.
129 * @param matrix The rotation matrix to create a euler rotation from
130 */
131 explicit EulerT(const SquareMatrixT3<T>& matrix);
132
133 /**
134 * Returns the yaw angle.
135 * @return Yaw angle in radian
136 */
137 inline const T& yaw() const;
138
139 /**
140 * Returns the yaw angle.
141 * @return Yaw angle in radian
142 */
143 inline T& yaw();
144
145 /**
146 * Returns the pitch angle.
147 * @return Pitch angle in radian
148 */
149 inline const T& pitch() const;
150
151 /**
152 * Returns the pitch angle.
153 * @return Pitch angle in radian
154 */
155 inline T& pitch();
156
157 /**
158 * Returns the roll angle.
159 * @return Roll angle in radian
160 */
161 inline const T& roll() const;
162
163 /**
164 * Returns the roll angle.
165 * @return Roll angle in radian
166 */
167 inline T& roll();
168
169 /**
170 * Returns whether the euler rotation holds valid parameters.
171 * @return True, if so
172 */
173 bool isValid() const;
174
175 /**
176 * Returns whether two euler rotations are identical up to a small epsilon.
177 * @param euler Right euler rotation
178 * @return True, if so
179 */
180 bool operator==(const EulerT<T>& euler) const;
181
182 /**
183 * Returns whether two euler rotations are not identical up to a small epsilon.
184 * @param euler Right euler rotation
185 * @return True, if so
186 */
187 inline bool operator!=(const EulerT<T>& euler) const;
188
189 /**
190 * Element access operator.
191 * @param index The index of the element to access, with range [0, 2]
192 * @return Element of the euler rotation
193 */
194 inline const T& operator[](const unsigned int index) const;
195
196 /**
197 * Element access operator.
198 * @param index The index of the element to access, with range [0, 2]
199 * @return Element of the euler rotation
200 */
201 inline T& operator[](const unsigned int index);
202
203 /**
204 * Element access operator.
205 * @param index The index of the element to access, with range [0, 2]
206 * @return Element of the euler rotation
207 */
208 inline const T& operator()(const unsigned int index) const;
209
210 /**
211 * Element access operator.
212 * @param index The index of the element to access, with range [0, 2]
213 * @return Element of the euler rotation
214 */
215 inline T& operator()(const unsigned int index);
216
217 /**
218 * Access operator.
219 * @return Pointer to the elements
220 */
221 inline const T* operator()() const;
222
223 /**
224 * Access operator.
225 * @return Pointer to the elements
226 */
227 inline T* operator()();
228
229 /**
230 * Decomposes a 3x3 rotation matrix to the corresponding yaw, pitch and roll angles as defined by the euler class.
231 * The provided rotation matrix can be recreated by the matrix product: Ry(yAngle) * Rx(xAngle) * Rz(zAngle).
232 * @param matrix The 3x3 square matrix to decompose, must be an orthonormal rotation matrix
233 * @param yAngle The resulting (yaw) angle (rotation around the y-axis), with range [-PI, PI]
234 * @param xAngle The resulting (pitch) angle (rotation around the x-axis), with range [-PI/2, PI/2]
235 * @param zAngle The resulting (roll) angle (rotation around the z-axis), with range [-PI, PI]
236 */
237 static void decomposeRotationMatrixToYXZ(const SquareMatrixT3<T>& matrix, T& yAngle, T& xAngle, T& zAngle);
238
239 /**
240 * Decomposes a 3x3 rotation matrix to the corresponding x, y and z angles.
241 * The provided rotation matrix can be recreated by the matrix product: Rx(xAngle) * Ry(yAngle) * Rz(zAngle).
242 * @param matrix The 3x3 square matrix to decompose, must be an orthonormal rotation matrix
243 * @param xAngle The resulting x angle (rotation around the x-axis), with range [-PI, PI]
244 * @param yAngle The resulting y angle (rotation around the y-axis), with range [-PI/2, PI/2]
245 * @param zAngle The resulting z angle (rotation around the z-axis), with range [-PI, PI]
246 */
247 static void decomposeRotationMatrixToXYZ(const SquareMatrixT3<T>& matrix, T& xAngle, T& yAngle, T& zAngle);
248
249 /**
250 * Adjusts euler angles with arbitrary value (e.g., outside the valid value range) to euler angles within the value range of a valid Euler object.
251 * @param yaw The yaw angle to be adjusted, in radian, afterwards will be in the value range of [-PI, PI], with range (-infinity, infinity)
252 * @param pitch The pitch angle to be adjusted, in radian, afterwards will be in the value range of [-PI/2, PI/2], with range (-infinity, infinity)
253 * @param roll The roll angle to be adjusted, in radian, afterwards will be in the value range of [-PI, PI], with range (-infinity, infinity)
254 */
255 static void adjustAngles(T& yaw, T& pitch, T& roll);
256
257 protected:
258
259 /// The three angles of the euler rotation.
261};
262
263template <typename T>
265{
266 values_[0] = T(0);
267 values_[1] = T(0);
268 values_[2] = T(0);
269}
270
271template <typename T>
272EulerT<T>::EulerT(const T yaw, const T pitch, const T roll)
273{
274 values_[0] = yaw;
275 values_[1] = pitch;
276 values_[2] = roll;
277}
278
279template <typename T>
280EulerT<T>::EulerT(const T* arrayValue)
281{
282 ocean_assert(arrayValue);
283 memcpy(values_, arrayValue, sizeof(T) * 3);
284}
285
286template <typename T>
288{
289 decomposeRotationMatrixToYXZ(transformation.orthonormalRotationMatrix(), values_[0], values_[1], values_[2]);
290 ocean_assert(isValid());
291}
292
293template <typename T>
295{
296 decomposeRotationMatrixToYXZ(SquareMatrixT3<T>(rotation), values_[0], values_[1], values_[2]);
297 ocean_assert(isValid());
298}
299
300template <typename T>
302{
303 decomposeRotationMatrixToYXZ(SquareMatrixT3<T>(quaternion), values_[0], values_[1], values_[2]);
304 ocean_assert(isValid());
305}
306
307template <typename T>
309{
310 decomposeRotationMatrixToYXZ(matrix, values_[0], values_[1], values_[2]);
311 ocean_assert(isValid());
312}
313
314template <typename T>
315inline const T& EulerT<T>::yaw() const
316{
317 return values_[0];
318}
319
320template <typename T>
321inline T& EulerT<T>::yaw()
322{
323 return values_[0];
324}
325
326template <typename T>
327inline const T& EulerT<T>::pitch() const
328{
329 return values_[1];
330}
331
332template <typename T>
334{
335 return values_[1];
336}
337
338template <typename T>
339inline const T& EulerT<T>::roll() const
340{
341 return values_[2];
342}
343
344template <typename T>
346{
347 return values_[2];
348}
349
350template <typename T>
357
358template <typename T>
359bool EulerT<T>::operator==(const EulerT<T>& euler) const
360{
361 return NumericT<T>::isEqual(values_[0], euler.values_[0]) && NumericT<T>::isEqual(values_[1], euler.values_[1]) && NumericT<T>::isEqual(values_[2], euler.values_[2]);
362}
363
364template <typename T>
365inline bool EulerT<T>::operator!=(const EulerT<T>& euler) const
366{
367 return !(*this == euler);
368}
369
370template <typename T>
371inline const T& EulerT<T>::operator[](const unsigned int index) const
372{
373 ocean_assert(index < 3u);
374 return values_[index];
375}
376
377template <typename T>
378inline T& EulerT<T>::operator[](const unsigned int index)
379{
380 ocean_assert(index < 3u);
381 return values_[index];
382}
383
384template <typename T>
385inline const T& EulerT<T>::operator()(const unsigned int index) const
386{
387 ocean_assert(index < 3u);
388 return values_[index];
389}
390
391template <typename T>
392inline T& EulerT<T>::operator()(const unsigned int index)
393{
394 ocean_assert(index < 3u);
395 return values_[index];
396}
397
398template <typename T>
399inline const T* EulerT<T>::operator()() const
400{
401 return values_;
402}
403
404template <typename T>
406{
407 return values_;
408}
409
410template <typename T>
411void EulerT<T>::decomposeRotationMatrixToYXZ(const SquareMatrixT3<T>& matrix, T& yAngle, T& xAngle, T& zAngle)
412{
413 ocean_assert(matrix.isOrthonormal());
414
415 /**
416 * Combined rotation matrix for R(y)R(x)R(z)
417 * [ cy cz + sx sy sz cz sx sy - cy sz cx sy ]
418 * [ cx sz cx cz -sx ]
419 * [ -cz sy + cy sx sz cy cz sx + sy sz cx cy ]
420 */
421
422 if (matrix(1, 2) > T(-1) + NumericT<T>::eps())
423 {
424 if (matrix(1, 2) < T(1) - NumericT<T>::eps())
425 {
426 // we have the normal case without any extreme angles
427
428 xAngle = NumericT<T>::asin(-matrix(1, 2));
429
430 ocean_assert(NumericT<T>::isNotEqualEps(matrix(0, 2)) || NumericT<T>::isNotEqualEps(matrix(2, 2)));
431 yAngle = NumericT<T>::atan2(matrix(0, 2), matrix(2, 2));
432
433 ocean_assert(NumericT<T>::isNotEqualEps(matrix(1, 0)) || NumericT<T>::isNotEqualEps(matrix(1, 1)));
434 zAngle = NumericT<T>::atan2(matrix(1, 0), matrix(1, 1));
435 }
436 else
437 {
438 // we have a special case where sx == -1
439 ocean_assert((std::is_same<float, T>::value) ? NumericT<T>::isWeakEqual(matrix(1, 2), 1) : NumericT<T>::isEqual(matrix(1, 2), 1));
440
441 /**
442 * Combined rotation matrix for R(y)R(x)R(z), with sx == -1 and cx == 0
443 * [ cy cz - sy sz - cz sy - cy sz 0 ] [ cos(y + z) -sin(y + z) 0 ]
444 * [ 0 0 -1 ] = [ 0 0 -1 ]
445 * [ -cz sy - cy sz - cy cz + sy sz 0 ] [ -sin(y + z) -cos(y + z) 0 ]
446 */
447
448 // tan(y + z) = sin(y + z) / cos(y + z), z == 0
449
450 yAngle = NumericT<T>::atan2(-matrix(0, 1), -matrix(2, 1));
451 xAngle = -NumericT<T>::pi_2();
452 zAngle = T(0.0);
453 }
454 }
455 else
456 {
457 // we have a special case where sx == 1
458 ocean_assert((std::is_same<float, T>::value) ? NumericT<T>::isWeakEqual(matrix(1, 2), -1) : NumericT<T>::isEqual(matrix(1, 2), -1));
459
460 /**
461 * Combined rotation matrix for R(y)R(x)R(z), with sx == 1 and cx == 0
462 * [ cy cz + sy sz cz sy - cy sz 0 ] [ cos(y - z) sin(y - z) 0 ]
463 * [ 0 0 -1 ] = [ 0 0 -1 ]
464 * [ -cz sy + cy sz cy cz + sy sz 0 ] [ sin(z - y) cos(y - z) 0 ]
465 */
466
467 // tan(y - z) = sin(y - z) / cos(y - z), z == 0
468
469 yAngle = NumericT<T>::atan2(matrix(0, 1), matrix(2, 1));
470 xAngle = NumericT<T>::pi_2();
471 zAngle = T(0.0);
472 }
473
477}
478
479template <typename T>
480void EulerT<T>::decomposeRotationMatrixToXYZ(const SquareMatrixT3<T>& matrix, T& xAngle, T& yAngle, T& zAngle)
481{
482 ocean_assert(matrix.isOrthonormal());
483
484 /**
485 * Combined rotation matrix for R(x)R(y)R(z)
486 * [ cy cz -cy sz sy ]
487 * [ cx sz + sx sy cz cx cz - sx sy sz -sx cy ]
488 * [ sx sz - cx sy cz sx cz + cx sy sz cx cy ]
489 */
490
491 if (matrix(0, 2) < T(1) - NumericT<T>::eps())
492 {
493 if (matrix(0, 2) > T(-1) + NumericT<T>::eps())
494 {
495 // we have the normal case without any extreme angles
496
497 ocean_assert(NumericT<T>::isNotEqualEps(matrix(1, 2)) || NumericT<T>::isNotEqualEps(matrix(2, 2)));
498 xAngle = NumericT<T>::atan2(-matrix(1, 2), matrix(2, 2));
499
500 yAngle = NumericT<T>::asin(matrix(0, 2));
501
502 ocean_assert(NumericT<T>::isNotEqualEps(matrix(0, 1)) || NumericT<T>::isNotEqualEps(matrix(0, 0)));
503 zAngle = NumericT<T>::atan2(-matrix(0, 1), matrix(0, 0));
504 }
505 else
506 {
507 // we have a special case where sx == -1
508 ocean_assert((std::is_same<float, T>::value) ? NumericT<T>::isWeakEqual(matrix(0, 2), -1) : NumericT<T>::isEqual(matrix(0, 2), -1));
509
510 /**
511 * Combined rotation matrix for R(x)R(y)R(z), with sy == -1 and cy == 0
512 * [ 0 0 1 ] [ 0 0 1 ]
513 * [ cx sz - sx cz cx cz + sx sz 0 ] = [ -sin(x - z) cos(x - z) 0 ]
514 * [ sx sz + cx cz sx cz - cx sz 0 ] [ cos(x - z) sin(x - z) 0 ]
515 */
516
517 // tan(x - z) = sin(x - z) / cos(x - z), z == 0
518
519 xAngle = NumericT<T>::atan2(matrix(2, 1), matrix(1, 1));
520 yAngle = -NumericT<T>::pi_2();
521 zAngle = T(0.0);
522 }
523 }
524 else
525 {
526 // we have a special case where sy == 1
527 ocean_assert((std::is_same<float, T>::value) ? NumericT<T>::isWeakEqual(matrix(0, 2), 1) : NumericT<T>::isEqual(matrix(0, 2), 1));
528
529 /**
530 * Combined rotation matrix for R(x)R(y)R(z), with sy == 1 and cy == 0
531 * [ 0 0 1 ] [ 0 0 1 ]
532 * [ cx sz + sx cz cx cz - sx sz 0 ] = [ sin(x + z) cos(x + z) 0 ]
533 * [ sx sz - cx cz sx cz + cx sz 0 ] [ -cos(x + z) sin(x + z) 0 ]
534 */
535
536 // tan(x + z) = sin(x + z) / cos(x + z), z == 0
537
538 xAngle = NumericT<T>::atan2(matrix(1, 0), matrix(1, 1));
539 yAngle = NumericT<T>::pi_2();
540 zAngle = T(0.0);
541 }
542
546}
547
548template <typename T>
549void EulerT<T>::adjustAngles(T& yaw, T& pitch, T& roll)
550{
551 pitch = NumericT<T>::angleAdjustNull(pitch);
552
553 if (NumericT<T>::abs(pitch) > NumericT<T>::pi_2())
554 {
555 pitch = NumericT<T>::copySign(NumericT<T>::pi(), pitch) - pitch;
556 yaw += NumericT<T>::pi();
557 roll += NumericT<T>::pi();
558 }
559
561 roll = NumericT<T>::angleAdjustNull(roll);
562
563 ocean_assert(Euler(yaw, pitch, roll).isValid());
564}
565
566}
567
568#endif // META_OCEAN_MATH_EULER_H
This class implements an euler rotation with angles: yaw, pitch and roll.
Definition Euler.h:80
EulerT()
Creates a new Euler rotation with all angles zero.
Definition Euler.h:264
static void decomposeRotationMatrixToXYZ(const SquareMatrixT3< T > &matrix, T &xAngle, T &yAngle, T &zAngle)
Decomposes a 3x3 rotation matrix to the corresponding x, y and z angles.
Definition Euler.h:480
const T & yaw() const
Returns the yaw angle.
Definition Euler.h:315
const T * operator()() const
Access operator.
Definition Euler.h:399
T values_[3]
The three angles of the euler rotation.
Definition Euler.h:260
const T & operator[](const unsigned int index) const
Element access operator.
Definition Euler.h:371
const T & roll() const
Returns the roll angle.
Definition Euler.h:339
bool operator!=(const EulerT< T > &euler) const
Returns whether two euler rotations are not identical up to a small epsilon.
Definition Euler.h:365
static void decomposeRotationMatrixToYXZ(const SquareMatrixT3< T > &matrix, T &yAngle, T &xAngle, T &zAngle)
Decomposes a 3x3 rotation matrix to the corresponding yaw, pitch and roll angles as defined by the eu...
Definition Euler.h:411
bool isValid() const
Returns whether the euler rotation holds valid parameters.
Definition Euler.h:351
T Type
Definition of the used data type.
Definition Euler.h:86
const T & pitch() const
Returns the pitch angle.
Definition Euler.h:327
static void adjustAngles(T &yaw, T &pitch, T &roll)
Adjusts euler angles with arbitrary value (e.g., outside the valid value range) to euler angles withi...
Definition Euler.h:549
bool operator==(const EulerT< T > &euler) const
Returns whether two euler rotations are identical up to a small epsilon.
Definition Euler.h:359
This class implements a 4x4 homogeneous transformation matrix using floating point values with the pr...
Definition HomogenousMatrix4.h:110
SquareMatrixT3< T > orthonormalRotationMatrix() const
Returns the 3x3 orthonormal rotation matrix of the 4x4 transformation (by forcing a orthogonal and no...
Definition HomogenousMatrix4.h:1538
This class provides basic numeric functionalities.
Definition Numeric.h:57
static constexpr bool isInsideRange(const T lower, const T value, const T upper, const T epsilon=NumericT< T >::eps())
Returns whether a value lies between a given range up to a provided epsilon border.
Definition Numeric.h:2872
static constexpr T pi_2()
Returns PI/2 which is equivalent to 90 degree.
Definition Numeric.h:938
static T atan2(const T y, const T x)
Returns the arctangent of a given value in radian.
Definition Numeric.h:1632
static constexpr T pi()
Returns PI which is equivalent to 180 degree.
Definition Numeric.h:926
static T angleAdjustNull(const T angle)
Adjusts an arbitrary angle into the range of (-PI, PI].
Definition Numeric.h:1794
static bool isEqual(const T first, const T second)
Returns whether two values are equal up to a small epsilon.
Definition Numeric.h:2386
static constexpr T copySign(const T signReceiver, const T signProvider)
Copies the sign of a given value to another one.
Definition Numeric.h:3264
static T asin(const T value)
Returns the arcsine of a given value.
Definition Numeric.h:2887
This class implements a unit quaternion rotation.
Definition Quaternion.h:100
This class implements a axis-angle rotation using floating point values.
Definition Rotation.h:79
This class implements a 3x3 square matrix.
Definition SquareMatrix3.h:88
bool isOrthonormal(const T epsilon=NumericT< T >::eps()) const
Returns whether this matrix is an orthonormal matrix.
Definition SquareMatrix3.h:1365
EulerT< float > EulerF
Instantiation of the EulerT template class using a single precision float data type.
Definition Euler.h:50
EulerT< Scalar > Euler
Definition of the Euler object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION either with single o...
Definition Euler.h:36
std::vector< Euler > Eulers
Definition of a vector holding euler objects.
Definition Euler.h:65
EulerT< double > EulerD
Instantiation of the EulerT template class using a double precision float data type.
Definition Euler.h:43
std::vector< EulerT< T > > EulersT
Definition of a typename alias for vectors with EulerT objects.
Definition Euler.h:58
The namespace covering the entire Ocean framework.
Definition Accessor.h:15