Eigen::EulerSystem< _AlphaAxis, _BetaAxis, _GammaAxis > Class Template Reference

Represents a fixed Euler rotation system. More...

Public Types

enum  {
  AlphaAxisAbs ,
  BetaAxisAbs ,
  GammaAxisAbs ,
  IsAlphaOpposite ,
  IsBetaOpposite ,
  IsGammaOpposite ,
  IsOdd ,
  IsEven ,
  IsTaitBryan
}
 

Static Public Attributes

static constexpr int AlphaAxis
 
static constexpr int BetaAxis
 
static constexpr int GammaAxis
 

Private Member Functions

 EIGEN_EULER_ANGLES_CLASS_STATIC_ASSERT ((unsigned) AlphaAxisAbs !=(unsigned) BetaAxisAbs, ALPHA_AXIS_CANT_BE_EQUAL_TO_BETA_AXIS)
 
 EIGEN_EULER_ANGLES_CLASS_STATIC_ASSERT ((unsigned) BetaAxisAbs !=(unsigned) GammaAxisAbs, BETA_AXIS_CANT_BE_EQUAL_TO_GAMMA_AXIS)
 
 EIGEN_EULER_ANGLES_CLASS_STATIC_ASSERT (internal::IsValidAxis< AlphaAxis >::value, ALPHA_AXIS_IS_INVALID)
 
 EIGEN_EULER_ANGLES_CLASS_STATIC_ASSERT (internal::IsValidAxis< BetaAxis >::value, BETA_AXIS_IS_INVALID)
 
 EIGEN_EULER_ANGLES_CLASS_STATIC_ASSERT (internal::IsValidAxis< GammaAxis >::value, GAMMA_AXIS_IS_INVALID)
 

Static Private Member Functions

template<typename Scalar >
static void CalcEulerAngles (EulerAngles< Scalar, EulerSystem > &res, const typename EulerAngles< Scalar, EulerSystem >::Matrix3 &mat)
 
template<typename Derived >
static void CalcEulerAngles_imp (Matrix< typename MatrixBase< Derived >::Scalar, 3, 1 > &res, const MatrixBase< Derived > &mat, internal::false_type)
 
template<typename Derived >
static void CalcEulerAngles_imp (Matrix< typename MatrixBase< Derived >::Scalar, 3, 1 > &res, const MatrixBase< Derived > &mat, internal::true_type)
 

Static Private Attributes

static const int I_
 
static const int J_
 
static const int K_
 

Detailed Description

template<int _AlphaAxis, int _BetaAxis, int _GammaAxis>
class Eigen::EulerSystem< _AlphaAxis, _BetaAxis, _GammaAxis >

Represents a fixed Euler rotation system.

This meta-class goal is to represent the Euler system in compilation time, for EulerAngles.

You can use this class to get two things:

  • Build an Euler system, and then pass it as a template parameter to EulerAngles.
  • Query some compile time data about an Euler system. (e.g. Whether it's Tait-Bryan)

Euler rotation is a set of three rotation on fixed axes. (see EulerAngles) This meta-class store constantly those signed axes. (see EulerAxis)

Types of Euler systems

All and only valid 3 dimension Euler rotation over standard signed axes{+X,+Y,+Z,-X,-Y,-Z} are supported:

  • all axes X, Y, Z in each valid order (see below what order is valid)
  • rotation over the axis is supported both over the positive and negative directions.
  • both Tait-Bryan and proper/classic Euler angles (i.e. the opposite).

Since EulerSystem support both positive and negative directions, you may call this rotation distinction in other names:

  • right handed or left handed
  • counterclockwise or clockwise

Notice all axed combination are valid, and would trigger a static assertion. Same unsigned axes can't be neighbors, e.g. {X,X,Y} is invalid. This yield two and only two classes:

  • Tait-Bryan - all unsigned axes are distinct, e.g. {X,Y,Z}
  • proper/classic Euler angles - The first and the third unsigned axes is equal, and the second is different, e.g. {X,Y,X}

Intrinsic vs extrinsic Euler systems

Only intrinsic Euler systems are supported for simplicity. If you want to use extrinsic Euler systems, just use the equal intrinsic opposite order for axes and angles. I.e axes (A,B,C) becomes (C,B,A), and angles (a,b,c) becomes (c,b,a).

Convenient user typedefs

Convenient typedefs for EulerSystem exist (only for positive axes Euler systems), in a form of EulerSystem{A}{B}{C}, e.g. EulerSystemXYZ.

Additional reading

More information about Euler angles: https://en.wikipedia.org/wiki/Euler_angles

Template Parameters
_AlphaAxisthe first fixed EulerAxis
_BetaAxisthe second fixed EulerAxis
_GammaAxisthe third fixed EulerAxis

Definition at line 128 of file EulerSystem.h.

Member Enumeration Documentation

◆ anonymous enum

template<int _AlphaAxis, int _BetaAxis, int _GammaAxis>
anonymous enum
Enumerator
AlphaAxisAbs 

the first rotation axis unsigned

BetaAxisAbs 

the second rotation axis unsigned

GammaAxisAbs 

the third rotation axis unsigned

IsAlphaOpposite 

whether alpha axis is negative

IsBetaOpposite 

whether beta axis is negative

IsGammaOpposite 

whether gamma axis is negative

IsOdd 

whether the Euler system is odd

IsEven 

whether the Euler system is even

IsTaitBryan 

whether the Euler system is Tait-Bryan

Definition at line 143 of file EulerSystem.h.

144  {
145  AlphaAxisAbs = internal::Abs<AlphaAxis>::value,
146  BetaAxisAbs = internal::Abs<BetaAxis>::value,
147  GammaAxisAbs = internal::Abs<GammaAxis>::value,
149  IsAlphaOpposite = (AlphaAxis < 0) ? 1 : 0,
150  IsBetaOpposite = (BetaAxis < 0) ? 1 : 0,
151  IsGammaOpposite = (GammaAxis < 0) ? 1 : 0,
153  // Parity is even if alpha axis X is followed by beta axis Y, or Y is followed
154  // by Z, or Z is followed by X; otherwise it is odd.
155  IsOdd = ((AlphaAxisAbs)%3 == (BetaAxisAbs - 1)%3) ? 0 : 1,
156  IsEven = IsOdd ? 0 : 1,
158  IsTaitBryan = ((unsigned)AlphaAxisAbs != (unsigned)GammaAxisAbs) ? 1 : 0
159  };
static constexpr int AlphaAxis
Definition: EulerSystem.h:135
static constexpr int GammaAxis
Definition: EulerSystem.h:141
static constexpr int BetaAxis
Definition: EulerSystem.h:138

Member Function Documentation

◆ CalcEulerAngles()

template<int _AlphaAxis, int _BetaAxis, int _GammaAxis>
template<typename Scalar >
static void Eigen::EulerSystem< _AlphaAxis, _BetaAxis, _GammaAxis >::CalcEulerAngles ( EulerAngles< Scalar, EulerSystem< _AlphaAxis, _BetaAxis, _GammaAxis > > &  res,
const typename EulerAngles< Scalar, EulerSystem< _AlphaAxis, _BetaAxis, _GammaAxis > >::Matrix3 mat 
)
inlinestaticprivate

Definition at line 259 of file EulerSystem.h.

262  {
264  res.angles(), mat,
265  std::conditional_t<IsTaitBryan, internal::true_type, internal::false_type>());
266 
267  if (IsAlphaOpposite)
268  res.alpha() = -res.alpha();
269 
270  if (IsBetaOpposite)
271  res.beta() = -res.beta();
272 
273  if (IsGammaOpposite)
274  res.gamma() = -res.gamma();
275  }
cout<< "Here is the matrix m:"<< endl<< m<< endl;Matrix< ptrdiff_t, 3, 1 > res
static void CalcEulerAngles_imp(Matrix< typename MatrixBase< Derived >::Scalar, 3, 1 > &res, const MatrixBase< Derived > &mat, internal::true_type)
Definition: EulerSystem.h:189

◆ CalcEulerAngles_imp() [1/2]

template<int _AlphaAxis, int _BetaAxis, int _GammaAxis>
template<typename Derived >
static void Eigen::EulerSystem< _AlphaAxis, _BetaAxis, _GammaAxis >::CalcEulerAngles_imp ( Matrix< typename MatrixBase< Derived >::Scalar, 3, 1 > &  res,
const MatrixBase< Derived > &  mat,
internal::false_type   
)
inlinestaticprivate

Definition at line 224 of file EulerSystem.h.

226  {
227  using std::atan2;
228  using std::sqrt;
229 
230  typedef typename Derived::Scalar Scalar;
231 
232  const Scalar plusMinus = IsEven? 1 : -1;
233  const Scalar minusPlus = IsOdd? 1 : -1;
234 
235  const Scalar Rsum = sqrt((mat(I_, J_) * mat(I_, J_) + mat(I_, K_) * mat(I_, K_) + mat(J_, I_) * mat(J_, I_) + mat(K_, I_) * mat(K_, I_)) / 2);
236 
237  res[1] = atan2(Rsum, mat(I_, I_));
238 
239  // There is a singularity when sin(beta) == 0
240  if(Rsum > 4 * NumTraits<Scalar>::epsilon()) {// sin(beta) != 0
241  res[0] = atan2(mat(J_, I_), minusPlus * mat(K_, I_));
242  res[2] = atan2(mat(I_, J_), plusMinus * mat(I_, K_));
243  }
244  else if(mat(I_, I_) > 0) {// sin(beta) == 0 and cos(beta) == 1
245  Scalar spos = plusMinus * mat(K_, J_) + minusPlus * mat(J_, K_); // 2*sin(alpha + gamma)
246  Scalar cpos = mat(J_, J_) + mat(K_, K_); // 2*cos(alpha + gamma)
247  res[0] = atan2(spos, cpos);
248  res[2] = 0;
249  }
250  else {// sin(beta) == 0 and cos(beta) == -1
251  Scalar sneg = plusMinus * mat(K_, J_) + plusMinus * mat(J_, K_); // 2*sin(alpha - gamma)
252  Scalar cneg = mat(J_, J_) - mat(K_, K_); // 2*cos(alpha - gamma)
253  res[0] = atan2(sneg, cneg);
254  res[2] = 0;
255  }
256  }
MatrixXf mat
static const int I_
Definition: EulerSystem.h:182
static const int J_
Definition: EulerSystem.h:183
static const int K_
Definition: EulerSystem.h:184
Eigen::AutoDiffScalar< EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(Eigen::internal::remove_all_t< DerType >, typename Eigen::internal::traits< Eigen::internal::remove_all_t< DerType >>::Scalar, product) > sqrt(const Eigen::AutoDiffScalar< DerType > &x)
AutoDiffScalar< Matrix< typename internal::traits< internal::remove_all_t< DerTypeA > >::Scalar, Dynamic, 1 > > atan2(const AutoDiffScalar< DerTypeA > &a, const AutoDiffScalar< DerTypeB > &b)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_sqrt_op< typename Derived::Scalar >, const Derived > sqrt(const Eigen::ArrayBase< Derived > &x)

◆ CalcEulerAngles_imp() [2/2]

template<int _AlphaAxis, int _BetaAxis, int _GammaAxis>
template<typename Derived >
static void Eigen::EulerSystem< _AlphaAxis, _BetaAxis, _GammaAxis >::CalcEulerAngles_imp ( Matrix< typename MatrixBase< Derived >::Scalar, 3, 1 > &  res,
const MatrixBase< Derived > &  mat,
internal::true_type   
)
inlinestaticprivate

Definition at line 189 of file EulerSystem.h.

190  {
191  using std::atan2;
192  using std::sqrt;
193 
194  typedef typename Derived::Scalar Scalar;
195 
196  const Scalar plusMinus = IsEven? 1 : -1;
197  const Scalar minusPlus = IsOdd? 1 : -1;
198 
199  const Scalar Rsum = sqrt((mat(I_,I_) * mat(I_,I_) + mat(I_,J_) * mat(I_,J_) + mat(J_,K_) * mat(J_,K_) + mat(K_,K_) * mat(K_,K_))/2);
200  res[1] = atan2(plusMinus * mat(I_,K_), Rsum);
201 
202  // There is a singularity when cos(beta) == 0
203  if(Rsum > 4 * NumTraits<Scalar>::epsilon()) {// cos(beta) != 0
204  res[0] = atan2(minusPlus * mat(J_, K_), mat(K_, K_));
205  res[2] = atan2(minusPlus * mat(I_, J_), mat(I_, I_));
206  }
207  else if(plusMinus * mat(I_, K_) > 0) {// cos(beta) == 0 and sin(beta) == 1
208  Scalar spos = mat(J_, I_) + plusMinus * mat(K_, J_); // 2*sin(alpha + plusMinus * gamma
209  Scalar cpos = mat(J_, J_) + minusPlus * mat(K_, I_); // 2*cos(alpha + plusMinus * gamma)
210  Scalar alphaPlusMinusGamma = atan2(spos, cpos);
211  res[0] = alphaPlusMinusGamma;
212  res[2] = 0;
213  }
214  else {// cos(beta) == 0 and sin(beta) == -1
215  Scalar sneg = plusMinus * (mat(K_, J_) + minusPlus * mat(J_, I_)); // 2*sin(alpha + minusPlus*gamma)
216  Scalar cneg = mat(J_, J_) + plusMinus * mat(K_, I_); // 2*cos(alpha + minusPlus*gamma)
217  Scalar alphaMinusPlusBeta = atan2(sneg, cneg);
218  res[0] = alphaMinusPlusBeta;
219  res[2] = 0;
220  }
221  }

◆ EIGEN_EULER_ANGLES_CLASS_STATIC_ASSERT() [1/5]

template<int _AlphaAxis, int _BetaAxis, int _GammaAxis>
Eigen::EulerSystem< _AlphaAxis, _BetaAxis, _GammaAxis >::EIGEN_EULER_ANGLES_CLASS_STATIC_ASSERT ( (unsigned) AlphaAxisAbs = (unsigned) BetaAxisAbs,
ALPHA_AXIS_CANT_BE_EQUAL_TO_BETA_AXIS   
)
private

◆ EIGEN_EULER_ANGLES_CLASS_STATIC_ASSERT() [2/5]

template<int _AlphaAxis, int _BetaAxis, int _GammaAxis>
Eigen::EulerSystem< _AlphaAxis, _BetaAxis, _GammaAxis >::EIGEN_EULER_ANGLES_CLASS_STATIC_ASSERT ( (unsigned) BetaAxisAbs = (unsigned) GammaAxisAbs,
BETA_AXIS_CANT_BE_EQUAL_TO_GAMMA_AXIS   
)
private

◆ EIGEN_EULER_ANGLES_CLASS_STATIC_ASSERT() [3/5]

template<int _AlphaAxis, int _BetaAxis, int _GammaAxis>
Eigen::EulerSystem< _AlphaAxis, _BetaAxis, _GammaAxis >::EIGEN_EULER_ANGLES_CLASS_STATIC_ASSERT ( internal::IsValidAxis< AlphaAxis >::value  ,
ALPHA_AXIS_IS_INVALID   
)
private

◆ EIGEN_EULER_ANGLES_CLASS_STATIC_ASSERT() [4/5]

template<int _AlphaAxis, int _BetaAxis, int _GammaAxis>
Eigen::EulerSystem< _AlphaAxis, _BetaAxis, _GammaAxis >::EIGEN_EULER_ANGLES_CLASS_STATIC_ASSERT ( internal::IsValidAxis< BetaAxis >::value  ,
BETA_AXIS_IS_INVALID   
)
private

◆ EIGEN_EULER_ANGLES_CLASS_STATIC_ASSERT() [5/5]

template<int _AlphaAxis, int _BetaAxis, int _GammaAxis>
Eigen::EulerSystem< _AlphaAxis, _BetaAxis, _GammaAxis >::EIGEN_EULER_ANGLES_CLASS_STATIC_ASSERT ( internal::IsValidAxis< GammaAxis >::value  ,
GAMMA_AXIS_IS_INVALID   
)
private

Member Data Documentation

◆ AlphaAxis

template<int _AlphaAxis, int _BetaAxis, int _GammaAxis>
constexpr int Eigen::EulerSystem< _AlphaAxis, _BetaAxis, _GammaAxis >::AlphaAxis
staticconstexpr

The first rotation axis

Definition at line 135 of file EulerSystem.h.

◆ BetaAxis

template<int _AlphaAxis, int _BetaAxis, int _GammaAxis>
constexpr int Eigen::EulerSystem< _AlphaAxis, _BetaAxis, _GammaAxis >::BetaAxis
staticconstexpr

The second rotation axis

Definition at line 138 of file EulerSystem.h.

◆ GammaAxis

template<int _AlphaAxis, int _BetaAxis, int _GammaAxis>
constexpr int Eigen::EulerSystem< _AlphaAxis, _BetaAxis, _GammaAxis >::GammaAxis
staticconstexpr

The third rotation axis

Definition at line 141 of file EulerSystem.h.

◆ I_

template<int _AlphaAxis, int _BetaAxis, int _GammaAxis>
const int Eigen::EulerSystem< _AlphaAxis, _BetaAxis, _GammaAxis >::I_
staticprivate

Definition at line 182 of file EulerSystem.h.

◆ J_

template<int _AlphaAxis, int _BetaAxis, int _GammaAxis>
const int Eigen::EulerSystem< _AlphaAxis, _BetaAxis, _GammaAxis >::J_
staticprivate

Definition at line 183 of file EulerSystem.h.

◆ K_

template<int _AlphaAxis, int _BetaAxis, int _GammaAxis>
const int Eigen::EulerSystem< _AlphaAxis, _BetaAxis, _GammaAxis >::K_
staticprivate

Definition at line 184 of file EulerSystem.h.


The documentation for this class was generated from the following file: