12b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// This file is part of Eigen, a lightweight C++ template library 22b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// for linear algebra. 32b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// 42b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Copyright (C) 2015 Tal Hadad <tal_hd@hotmail.com> 52b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// 62b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// This Source Code Form is subject to the terms of the Mozilla 72b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Public License v. 2.0. If a copy of the MPL was not distributed 82b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 92b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#ifndef EIGEN_EULERANGLESCLASS_H// TODO: Fix previous "EIGEN_EULERANGLES_H" definition? 112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#define EIGEN_EULERANGLESCLASS_H 122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangnamespace Eigen 142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /*template<typename Other, 162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang int OtherRows=Other::RowsAtCompileTime, 172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang int OtherCols=Other::ColsAtCompileTime> 182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang struct ei_eulerangles_assign_impl;*/ 192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** \class EulerAngles 212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \ingroup EulerAngles_Module 232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \brief Represents a rotation in a 3 dimensional space as three Euler angles. 252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * Euler rotation is a set of three rotation of three angles over three fixed axes, defined by the EulerSystem given as a template parameter. 272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * Here is how intrinsic Euler angles works: 292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * - first, rotate the axes system over the alpha axis in angle alpha 302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * - then, rotate the axes system over the beta axis(which was rotated in the first stage) in angle beta 312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * - then, rotate the axes system over the gamma axis(which was rotated in the two stages above) in angle gamma 322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \note This class support only intrinsic Euler angles for simplicity, 342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * see EulerSystem how to easily overcome this for extrinsic systems. 352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * ### Rotation representation and conversions ### 372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * It has been proved(see Wikipedia link below) that every rotation can be represented 392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * by Euler angles, but there is no singular representation (e.g. unlike rotation matrices). 402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * Therefore, you can convert from Eigen rotation and to them 412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * (including rotation matrices, which is not called "rotations" by Eigen design). 422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * Euler angles usually used for: 442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * - convenient human representation of rotation, especially in interactive GUI. 452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * - gimbal systems and robotics 462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * - efficient encoding(i.e. 3 floats only) of rotation for network protocols. 472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * However, Euler angles are slow comparing to quaternion or matrices, 492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * because their unnatural math definition, although it's simple for human. 502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * To overcome this, this class provide easy movement from the math friendly representation 512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * to the human friendly representation, and vise-versa. 522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * All the user need to do is a safe simple C++ type conversion, 542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * and this class take care for the math. 552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * Additionally, some axes related computation is done in compile time. 562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * #### Euler angles ranges in conversions #### 582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * When converting some rotation to Euler angles, there are some ways you can guarantee 602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * the Euler angles ranges. 612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * #### implicit ranges #### 632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * When using implicit ranges, all angles are guarantee to be in the range [-PI, +PI], 642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * unless you convert from some other Euler angles. 652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * In this case, the range is __undefined__ (might be even less than -PI or greater than +2*PI). 662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \sa EulerAngles(const MatrixBase<Derived>&) 672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \sa EulerAngles(const RotationBase<Derived, 3>&) 682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * #### explicit ranges #### 702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * When using explicit ranges, all angles are guarantee to be in the range you choose. 712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * In the range Boolean parameter, you're been ask whether you prefer the positive range or not: 722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * - _true_ - force the range between [0, +2*PI] 732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * - _false_ - force the range between [-PI, +PI] 742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * ##### compile time ranges ##### 762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * This is when you have compile time ranges and you prefer to 772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * use template parameter. (e.g. for performance) 782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \sa FromRotation() 792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * ##### run-time time ranges ##### 812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * Run-time ranges are also supported. 822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \sa EulerAngles(const MatrixBase<Derived>&, bool, bool, bool) 832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \sa EulerAngles(const RotationBase<Derived, 3>&, bool, bool, bool) 842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * ### Convenient user typedefs ### 862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * Convenient typedefs for EulerAngles exist for float and double scalar, 882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * in a form of EulerAngles{A}{B}{C}{scalar}, 892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * e.g. \ref EulerAnglesXYZd, \ref EulerAnglesZYZf. 902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * Only for positive axes{+x,+y,+z} Euler systems are have convenient typedef. 922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * If you need negative axes{-x,-y,-z}, it is recommended to create you own typedef with 932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * a word that represent what you need. 942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * ### Example ### 962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \include EulerAngles.cpp 982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * Output: \verbinclude EulerAngles.out 992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 1002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * ### Additional reading ### 1012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 1022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * If you're want to get more idea about how Euler system work in Eigen see EulerSystem. 1032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 1042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * More information about Euler angles: https://en.wikipedia.org/wiki/Euler_angles 1052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 1062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \tparam _Scalar the scalar type, i.e., the type of the angles. 1072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 1082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \tparam _System the EulerSystem to use, which represents the axes of rotation. 1092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang */ 1102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template <typename _Scalar, class _System> 1112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang class EulerAngles : public RotationBase<EulerAngles<_Scalar, _System>, 3> 1122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 1132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang public: 1142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** the scalar type of the angles */ 1152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef _Scalar Scalar; 1162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** the EulerSystem to use, which represents the axes of rotation. */ 1182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef _System System; 1192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef Matrix<Scalar,3,3> Matrix3; /*!< the equivalent rotation matrix type */ 1212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef Matrix<Scalar,3,1> Vector3; /*!< the equivalent 3 dimension vector type */ 1222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef Quaternion<Scalar> QuaternionType; /*!< the equivalent quaternion type */ 1232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef AngleAxis<Scalar> AngleAxisType; /*!< the equivalent angle-axis type */ 1242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** \returns the axis vector of the first (alpha) rotation */ 1262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang static Vector3 AlphaAxisVector() { 1272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const Vector3& u = Vector3::Unit(System::AlphaAxisAbs - 1); 1282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return System::IsAlphaOpposite ? -u : u; 1292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 1302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** \returns the axis vector of the second (beta) rotation */ 1322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang static Vector3 BetaAxisVector() { 1332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const Vector3& u = Vector3::Unit(System::BetaAxisAbs - 1); 1342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return System::IsBetaOpposite ? -u : u; 1352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 1362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** \returns the axis vector of the third (gamma) rotation */ 1382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang static Vector3 GammaAxisVector() { 1392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const Vector3& u = Vector3::Unit(System::GammaAxisAbs - 1); 1402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return System::IsGammaOpposite ? -u : u; 1412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 1422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang private: 1442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Vector3 m_angles; 1452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang public: 1472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** Default constructor without initialization. */ 1482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EulerAngles() {} 1492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** Constructs and initialize Euler angles(\p alpha, \p beta, \p gamma). */ 1502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EulerAngles(const Scalar& alpha, const Scalar& beta, const Scalar& gamma) : 1512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_angles(alpha, beta, gamma) {} 1522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** Constructs and initialize Euler angles from a 3x3 rotation matrix \p m. 1542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 1552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \note All angles will be in the range [-PI, PI]. 1562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang */ 1572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<typename Derived> 1582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EulerAngles(const MatrixBase<Derived>& m) { *this = m; } 1592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** Constructs and initialize Euler angles from a 3x3 rotation matrix \p m, 1612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * with options to choose for each angle the requested range. 1622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 1632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * If positive range is true, then the specified angle will be in the range [0, +2*PI]. 1642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * Otherwise, the specified angle will be in the range [-PI, +PI]. 1652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 1662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \param m The 3x3 rotation matrix to convert 1672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \param positiveRangeAlpha If true, alpha will be in [0, 2*PI]. Otherwise, in [-PI, +PI]. 1682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \param positiveRangeBeta If true, beta will be in [0, 2*PI]. Otherwise, in [-PI, +PI]. 1692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \param positiveRangeGamma If true, gamma will be in [0, 2*PI]. Otherwise, in [-PI, +PI]. 1702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang */ 1712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<typename Derived> 1722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EulerAngles( 1732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const MatrixBase<Derived>& m, 1742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang bool positiveRangeAlpha, 1752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang bool positiveRangeBeta, 1762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang bool positiveRangeGamma) { 1772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang System::CalcEulerAngles(*this, m, positiveRangeAlpha, positiveRangeBeta, positiveRangeGamma); 1792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 1802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** Constructs and initialize Euler angles from a rotation \p rot. 1822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 1832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \note All angles will be in the range [-PI, PI], unless \p rot is an EulerAngles. 1842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * If rot is an EulerAngles, expected EulerAngles range is __undefined__. 1852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * (Use other functions here for enforcing range if this effect is desired) 1862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang */ 1872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<typename Derived> 1882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EulerAngles(const RotationBase<Derived, 3>& rot) { *this = rot; } 1892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** Constructs and initialize Euler angles from a rotation \p rot, 1912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * with options to choose for each angle the requested range. 1922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 1932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * If positive range is true, then the specified angle will be in the range [0, +2*PI]. 1942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * Otherwise, the specified angle will be in the range [-PI, +PI]. 1952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 1962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \param rot The 3x3 rotation matrix to convert 1972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \param positiveRangeAlpha If true, alpha will be in [0, 2*PI]. Otherwise, in [-PI, +PI]. 1982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \param positiveRangeBeta If true, beta will be in [0, 2*PI]. Otherwise, in [-PI, +PI]. 1992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \param positiveRangeGamma If true, gamma will be in [0, 2*PI]. Otherwise, in [-PI, +PI]. 2002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang */ 2012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<typename Derived> 2022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EulerAngles( 2032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const RotationBase<Derived, 3>& rot, 2042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang bool positiveRangeAlpha, 2052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang bool positiveRangeBeta, 2062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang bool positiveRangeGamma) { 2072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang System::CalcEulerAngles(*this, rot.toRotationMatrix(), positiveRangeAlpha, positiveRangeBeta, positiveRangeGamma); 2092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 2102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** \returns The angle values stored in a vector (alpha, beta, gamma). */ 2122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const Vector3& angles() const { return m_angles; } 2132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** \returns A read-write reference to the angle values stored in a vector (alpha, beta, gamma). */ 2142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Vector3& angles() { return m_angles; } 2152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** \returns The value of the first angle. */ 2172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Scalar alpha() const { return m_angles[0]; } 2182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** \returns A read-write reference to the angle of the first angle. */ 2192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Scalar& alpha() { return m_angles[0]; } 2202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** \returns The value of the second angle. */ 2222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Scalar beta() const { return m_angles[1]; } 2232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** \returns A read-write reference to the angle of the second angle. */ 2242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Scalar& beta() { return m_angles[1]; } 2252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** \returns The value of the third angle. */ 2272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Scalar gamma() const { return m_angles[2]; } 2282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** \returns A read-write reference to the angle of the third angle. */ 2292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Scalar& gamma() { return m_angles[2]; } 2302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** \returns The Euler angles rotation inverse (which is as same as the negative), 2322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * (-alpha, -beta, -gamma). 2332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang */ 2342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EulerAngles inverse() const 2352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 2362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EulerAngles res; 2372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang res.m_angles = -m_angles; 2382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return res; 2392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 2402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** \returns The Euler angles rotation negative (which is as same as the inverse), 2422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * (-alpha, -beta, -gamma). 2432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang */ 2442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EulerAngles operator -() const 2452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 2462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return inverse(); 2472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 2482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** Constructs and initialize Euler angles from a 3x3 rotation matrix \p m, 2502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * with options to choose for each angle the requested range (__only in compile time__). 2512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 2522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * If positive range is true, then the specified angle will be in the range [0, +2*PI]. 2532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * Otherwise, the specified angle will be in the range [-PI, +PI]. 2542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 2552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \param m The 3x3 rotation matrix to convert 2562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \tparam positiveRangeAlpha If true, alpha will be in [0, 2*PI]. Otherwise, in [-PI, +PI]. 2572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \tparam positiveRangeBeta If true, beta will be in [0, 2*PI]. Otherwise, in [-PI, +PI]. 2582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \tparam positiveRangeGamma If true, gamma will be in [0, 2*PI]. Otherwise, in [-PI, +PI]. 2592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang */ 2602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template< 2612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang bool PositiveRangeAlpha, 2622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang bool PositiveRangeBeta, 2632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang bool PositiveRangeGamma, 2642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typename Derived> 2652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang static EulerAngles FromRotation(const MatrixBase<Derived>& m) 2662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 2672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 3, 3) 2682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EulerAngles e; 2702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang System::template CalcEulerAngles< 2712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang PositiveRangeAlpha, PositiveRangeBeta, PositiveRangeGamma, _Scalar>(e, m); 2722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return e; 2732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 2742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** Constructs and initialize Euler angles from a rotation \p rot, 2762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * with options to choose for each angle the requested range (__only in compile time__). 2772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 2782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * If positive range is true, then the specified angle will be in the range [0, +2*PI]. 2792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * Otherwise, the specified angle will be in the range [-PI, +PI]. 2802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 2812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \param rot The 3x3 rotation matrix to convert 2822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \tparam positiveRangeAlpha If true, alpha will be in [0, 2*PI]. Otherwise, in [-PI, +PI]. 2832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \tparam positiveRangeBeta If true, beta will be in [0, 2*PI]. Otherwise, in [-PI, +PI]. 2842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \tparam positiveRangeGamma If true, gamma will be in [0, 2*PI]. Otherwise, in [-PI, +PI]. 2852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang */ 2862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template< 2872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang bool PositiveRangeAlpha, 2882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang bool PositiveRangeBeta, 2892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang bool PositiveRangeGamma, 2902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typename Derived> 2912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang static EulerAngles FromRotation(const RotationBase<Derived, 3>& rot) 2922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 2932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return FromRotation<PositiveRangeAlpha, PositiveRangeBeta, PositiveRangeGamma>(rot.toRotationMatrix()); 2942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 2952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /*EulerAngles& fromQuaternion(const QuaternionType& q) 2972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 2982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // TODO: Implement it in a faster way for quaternions 2992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // According to http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/ 3002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // we can compute only the needed matrix cells and then convert to euler angles. (see ZYX example below) 3012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // Currently we compute all matrix cells from quaternion. 3022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 3032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // Special case only for ZYX 3042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang //Scalar y2 = q.y() * q.y(); 3052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang //m_angles[0] = std::atan2(2*(q.w()*q.z() + q.x()*q.y()), (1 - 2*(y2 + q.z()*q.z()))); 3062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang //m_angles[1] = std::asin( 2*(q.w()*q.y() - q.z()*q.x())); 3072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang //m_angles[2] = std::atan2(2*(q.w()*q.x() + q.y()*q.z()), (1 - 2*(q.x()*q.x() + y2))); 3082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang }*/ 3092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 3102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** Set \c *this from a rotation matrix(i.e. pure orthogonal matrix with determinant of +1). */ 3112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<typename Derived> 3122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EulerAngles& operator=(const MatrixBase<Derived>& m) { 3132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 3, 3) 3142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 3152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang System::CalcEulerAngles(*this, m); 3162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return *this; 3172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 3182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 3192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // TODO: Assign and construct from another EulerAngles (with different system) 3202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 3212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** Set \c *this from a rotation. */ 3222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<typename Derived> 3232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EulerAngles& operator=(const RotationBase<Derived, 3>& rot) { 3242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang System::CalcEulerAngles(*this, rot.toRotationMatrix()); 3252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return *this; 3262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 3272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 3282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // TODO: Support isApprox function 3292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 3302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** \returns an equivalent 3x3 rotation matrix. */ 3312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Matrix3 toRotationMatrix() const 3322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 3332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return static_cast<QuaternionType>(*this).toRotationMatrix(); 3342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 3352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 3362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** Convert the Euler angles to quaternion. */ 3372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang operator QuaternionType() const 3382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 3392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return 3402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang AngleAxisType(alpha(), AlphaAxisVector()) * 3412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang AngleAxisType(beta(), BetaAxisVector()) * 3422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang AngleAxisType(gamma(), GammaAxisVector()); 3432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 3442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 3452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang friend std::ostream& operator<<(std::ostream& s, const EulerAngles<Scalar, System>& eulerAngles) 3462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 3472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang s << eulerAngles.angles().transpose(); 3482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return s; 3492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 3502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang }; 3512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 3522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#define EIGEN_EULER_ANGLES_SINGLE_TYPEDEF(AXES, SCALAR_TYPE, SCALAR_POSTFIX) \ 3532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** \ingroup EulerAngles_Module */ \ 3542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef EulerAngles<SCALAR_TYPE, EulerSystem##AXES> EulerAngles##AXES##SCALAR_POSTFIX; 3552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 3562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#define EIGEN_EULER_ANGLES_TYPEDEFS(SCALAR_TYPE, SCALAR_POSTFIX) \ 3572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_EULER_ANGLES_SINGLE_TYPEDEF(XYZ, SCALAR_TYPE, SCALAR_POSTFIX) \ 3582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_EULER_ANGLES_SINGLE_TYPEDEF(XYX, SCALAR_TYPE, SCALAR_POSTFIX) \ 3592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_EULER_ANGLES_SINGLE_TYPEDEF(XZY, SCALAR_TYPE, SCALAR_POSTFIX) \ 3602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_EULER_ANGLES_SINGLE_TYPEDEF(XZX, SCALAR_TYPE, SCALAR_POSTFIX) \ 3612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang \ 3622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_EULER_ANGLES_SINGLE_TYPEDEF(YZX, SCALAR_TYPE, SCALAR_POSTFIX) \ 3632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_EULER_ANGLES_SINGLE_TYPEDEF(YZY, SCALAR_TYPE, SCALAR_POSTFIX) \ 3642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_EULER_ANGLES_SINGLE_TYPEDEF(YXZ, SCALAR_TYPE, SCALAR_POSTFIX) \ 3652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_EULER_ANGLES_SINGLE_TYPEDEF(YXY, SCALAR_TYPE, SCALAR_POSTFIX) \ 3662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang \ 3672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_EULER_ANGLES_SINGLE_TYPEDEF(ZXY, SCALAR_TYPE, SCALAR_POSTFIX) \ 3682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_EULER_ANGLES_SINGLE_TYPEDEF(ZXZ, SCALAR_TYPE, SCALAR_POSTFIX) \ 3692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_EULER_ANGLES_SINGLE_TYPEDEF(ZYX, SCALAR_TYPE, SCALAR_POSTFIX) \ 3702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_EULER_ANGLES_SINGLE_TYPEDEF(ZYZ, SCALAR_TYPE, SCALAR_POSTFIX) 3712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 3722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao WangEIGEN_EULER_ANGLES_TYPEDEFS(float, f) 3732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao WangEIGEN_EULER_ANGLES_TYPEDEFS(double, d) 3742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 3752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang namespace internal 3762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 3772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<typename _Scalar, class _System> 3782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang struct traits<EulerAngles<_Scalar, _System> > 3792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 3802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef _Scalar Scalar; 3812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang }; 3822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 3832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 3842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang} 3852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 3862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#endif // EIGEN_EULERANGLESCLASS_H 387