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