Eigen-Contrib  5.0.1
 
Loading...
Searching...
No Matches
EulerSystem.h
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2015 Tal Hadad <tal_hd@hotmail.com>
5//
6// This Source Code Form is subject to the terms of the Mozilla
7// Public License v. 2.0. If a copy of the MPL was not distributed
8// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9// SPDX-License-Identifier: MPL-2.0
10
11#ifndef EIGEN_EULERSYSTEM_H
12#define EIGEN_EULERSYSTEM_H
13
14// IWYU pragma: private
15#include "./InternalHeaderCheck.h"
16
17namespace Eigen {
18// Forward declarations
19template <typename Scalar_, class _System>
20class EulerAngles;
21
22namespace internal {
23// TODO: Add this trait to the Eigen internal API?
24template <int Num, bool IsPositive = (Num > 0)>
25struct Abs : std::integral_constant<int, Num> {};
26
27template <int Num>
28struct Abs<Num, false> : std::integral_constant<int, -Num> {};
29
30template <int Axis>
31struct IsValidAxis : bool_constant<Axis != 0 && Abs<Axis>::value <= 3> {};
32
33template <typename System, typename Other, int OtherRows = Other::RowsAtCompileTime,
34 int OtherCols = Other::ColsAtCompileTime>
35struct eulerangles_assign_impl;
36} // namespace internal
37
38#define EIGEN_EULER_ANGLES_CLASS_STATIC_ASSERT(COND, MSG) typedef char static_assertion_##MSG[(COND) ? 1 : -1]
39
52enum EulerAxis {
53 EULER_X = 1,
54 EULER_Y = 2,
55 EULER_Z = 3
56};
57
115template <int _AlphaAxis, int _BetaAxis, int _GammaAxis>
116class EulerSystem {
117 public:
118 // Defined as static constexpr rather than enum to ensure support for negative values.
119
121 static constexpr int AlphaAxis = _AlphaAxis;
122
124 static constexpr int BetaAxis = _BetaAxis;
125
127 static constexpr int GammaAxis = _GammaAxis;
128
129 enum {
130 AlphaAxisAbs = internal::Abs<AlphaAxis>::value,
131 BetaAxisAbs = internal::Abs<BetaAxis>::value,
132 GammaAxisAbs = internal::Abs<GammaAxis>::value,
133
134 IsAlphaOpposite = (AlphaAxis < 0) ? 1 : 0,
135 IsBetaOpposite = (BetaAxis < 0) ? 1 : 0,
136 IsGammaOpposite = (GammaAxis < 0) ? 1 : 0,
137
138 // Parity is even if alpha axis X is followed by beta axis Y, or Y is followed
139 // by Z, or Z is followed by X; otherwise it is odd.
140 IsOdd = (AlphaAxisAbs % 3 == (BetaAxisAbs - 1) % 3) ? 0 : 1,
141 IsEven = IsOdd ? 0 : 1,
142
143 IsTaitBryan =
144 ((unsigned)AlphaAxisAbs != (unsigned)GammaAxisAbs) ? 1 : 0
145 };
146
147 private:
148 EIGEN_EULER_ANGLES_CLASS_STATIC_ASSERT(internal::IsValidAxis<AlphaAxis>::value, ALPHA_AXIS_IS_INVALID);
149
150 EIGEN_EULER_ANGLES_CLASS_STATIC_ASSERT(internal::IsValidAxis<BetaAxis>::value, BETA_AXIS_IS_INVALID);
151
152 EIGEN_EULER_ANGLES_CLASS_STATIC_ASSERT(internal::IsValidAxis<GammaAxis>::value, GAMMA_AXIS_IS_INVALID);
153
154 EIGEN_EULER_ANGLES_CLASS_STATIC_ASSERT((unsigned)AlphaAxisAbs != (unsigned)BetaAxisAbs,
155 ALPHA_AXIS_CANT_BE_EQUAL_TO_BETA_AXIS);
156
157 EIGEN_EULER_ANGLES_CLASS_STATIC_ASSERT((unsigned)BetaAxisAbs != (unsigned)GammaAxisAbs,
158 BETA_AXIS_CANT_BE_EQUAL_TO_GAMMA_AXIS);
159
160 template <typename Scalar>
161 static void CalcEulerAngles(EulerAngles<Scalar, EulerSystem>& res,
162 const typename EulerAngles<Scalar, EulerSystem>::Matrix3& mat) {
163 res.angles() = mat.canonicalEulerAngles(AlphaAxisAbs - 1, BetaAxisAbs - 1, GammaAxisAbs - 1);
164
165 EIGEN_IF_CONSTEXPR (IsAlphaOpposite) res.alpha() = -res.alpha();
166
167 EIGEN_IF_CONSTEXPR (IsBetaOpposite) res.beta() = -res.beta();
168
169 EIGEN_IF_CONSTEXPR (IsGammaOpposite) res.gamma() = -res.gamma();
170 }
171
172 template <typename Scalar_, class _System>
173 friend class Eigen::EulerAngles;
174
175 template <typename System, typename Other, int OtherRows, int OtherCols>
176 friend struct internal::eulerangles_assign_impl;
177};
178
179#define EIGEN_EULER_SYSTEM_TYPEDEF(A, B, C) typedef EulerSystem<EULER_##A, EULER_##B, EULER_##C> EulerSystem##A##B##C;
180
184EIGEN_EULER_SYSTEM_TYPEDEF(X, Y, Z)
185EIGEN_EULER_SYSTEM_TYPEDEF(X, Y, X)
186EIGEN_EULER_SYSTEM_TYPEDEF(X, Z, Y)
187EIGEN_EULER_SYSTEM_TYPEDEF(X, Z, X)
188
189EIGEN_EULER_SYSTEM_TYPEDEF(Y, Z, X)
190EIGEN_EULER_SYSTEM_TYPEDEF(Y, Z, Y)
191EIGEN_EULER_SYSTEM_TYPEDEF(Y, X, Z)
192EIGEN_EULER_SYSTEM_TYPEDEF(Y, X, Y)
193
194EIGEN_EULER_SYSTEM_TYPEDEF(Z, X, Y)
195EIGEN_EULER_SYSTEM_TYPEDEF(Z, X, Z)
196EIGEN_EULER_SYSTEM_TYPEDEF(Z, Y, X)
197EIGEN_EULER_SYSTEM_TYPEDEF(Z, Y, Z)
198} // namespace Eigen
199
200#undef EIGEN_EULER_ANGLES_CLASS_STATIC_ASSERT
201#undef EIGEN_EULER_SYSTEM_TYPEDEF
202
203#endif // EIGEN_EULERSYSTEM_H
Represents a rotation in a 3 dimensional space as three Euler angles.
Definition EulerAngles.h:104
Namespace containing all symbols from the Eigen library.