1*bf2c3715SXin Li // This file is part of Eigen, a lightweight C++ template library 2*bf2c3715SXin Li // for linear algebra. 3*bf2c3715SXin Li // 4*bf2c3715SXin Li // Copyright (C) 2008 Gael Guennebaud <[email protected]> 5*bf2c3715SXin Li // 6*bf2c3715SXin Li // This Source Code Form is subject to the terms of the Mozilla 7*bf2c3715SXin Li // Public License v. 2.0. If a copy of the MPL was not distributed 8*bf2c3715SXin Li // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9*bf2c3715SXin Li 10*bf2c3715SXin Li #ifndef EIGEN_ROTATIONBASE_H 11*bf2c3715SXin Li #define EIGEN_ROTATIONBASE_H 12*bf2c3715SXin Li 13*bf2c3715SXin Li namespace Eigen { 14*bf2c3715SXin Li 15*bf2c3715SXin Li // forward declaration 16*bf2c3715SXin Li namespace internal { 17*bf2c3715SXin Li template<typename RotationDerived, typename MatrixType, bool IsVector=MatrixType::IsVectorAtCompileTime> 18*bf2c3715SXin Li struct rotation_base_generic_product_selector; 19*bf2c3715SXin Li } 20*bf2c3715SXin Li 21*bf2c3715SXin Li /** \class RotationBase 22*bf2c3715SXin Li * 23*bf2c3715SXin Li * \brief Common base class for compact rotation representations 24*bf2c3715SXin Li * 25*bf2c3715SXin Li * \tparam Derived is the derived type, i.e., a rotation type 26*bf2c3715SXin Li * \tparam _Dim the dimension of the space 27*bf2c3715SXin Li */ 28*bf2c3715SXin Li template<typename Derived, int _Dim> 29*bf2c3715SXin Li class RotationBase 30*bf2c3715SXin Li { 31*bf2c3715SXin Li public: 32*bf2c3715SXin Li enum { Dim = _Dim }; 33*bf2c3715SXin Li /** the scalar type of the coefficients */ 34*bf2c3715SXin Li typedef typename internal::traits<Derived>::Scalar Scalar; 35*bf2c3715SXin Li 36*bf2c3715SXin Li /** corresponding linear transformation matrix type */ 37*bf2c3715SXin Li typedef Matrix<Scalar,Dim,Dim> RotationMatrixType; 38*bf2c3715SXin Li typedef Matrix<Scalar,Dim,1> VectorType; 39*bf2c3715SXin Li 40*bf2c3715SXin Li public: derived()41*bf2c3715SXin Li EIGEN_DEVICE_FUNC inline const Derived& derived() const { return *static_cast<const Derived*>(this); } derived()42*bf2c3715SXin Li EIGEN_DEVICE_FUNC inline Derived& derived() { return *static_cast<Derived*>(this); } 43*bf2c3715SXin Li 44*bf2c3715SXin Li /** \returns an equivalent rotation matrix */ toRotationMatrix()45*bf2c3715SXin Li EIGEN_DEVICE_FUNC inline RotationMatrixType toRotationMatrix() const { return derived().toRotationMatrix(); } 46*bf2c3715SXin Li 47*bf2c3715SXin Li /** \returns an equivalent rotation matrix 48*bf2c3715SXin Li * This function is added to be conform with the Transform class' naming scheme. 49*bf2c3715SXin Li */ matrix()50*bf2c3715SXin Li EIGEN_DEVICE_FUNC inline RotationMatrixType matrix() const { return derived().toRotationMatrix(); } 51*bf2c3715SXin Li 52*bf2c3715SXin Li /** \returns the inverse rotation */ inverse()53*bf2c3715SXin Li EIGEN_DEVICE_FUNC inline Derived inverse() const { return derived().inverse(); } 54*bf2c3715SXin Li 55*bf2c3715SXin Li /** \returns the concatenation of the rotation \c *this with a translation \a t */ 56*bf2c3715SXin Li EIGEN_DEVICE_FUNC inline Transform<Scalar,Dim,Isometry> operator*(const Translation<Scalar,Dim>& t) const 57*bf2c3715SXin Li { return Transform<Scalar,Dim,Isometry>(*this) * t; } 58*bf2c3715SXin Li 59*bf2c3715SXin Li /** \returns the concatenation of the rotation \c *this with a uniform scaling \a s */ 60*bf2c3715SXin Li EIGEN_DEVICE_FUNC inline RotationMatrixType operator*(const UniformScaling<Scalar>& s) const 61*bf2c3715SXin Li { return toRotationMatrix() * s.factor(); } 62*bf2c3715SXin Li 63*bf2c3715SXin Li /** \returns the concatenation of the rotation \c *this with a generic expression \a e 64*bf2c3715SXin Li * \a e can be: 65*bf2c3715SXin Li * - a DimxDim linear transformation matrix 66*bf2c3715SXin Li * - a DimxDim diagonal matrix (axis aligned scaling) 67*bf2c3715SXin Li * - a vector of size Dim 68*bf2c3715SXin Li */ 69*bf2c3715SXin Li template<typename OtherDerived> 70*bf2c3715SXin Li EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::rotation_base_generic_product_selector<Derived,OtherDerived,OtherDerived::IsVectorAtCompileTime>::ReturnType 71*bf2c3715SXin Li operator*(const EigenBase<OtherDerived>& e) const 72*bf2c3715SXin Li { return internal::rotation_base_generic_product_selector<Derived,OtherDerived>::run(derived(), e.derived()); } 73*bf2c3715SXin Li 74*bf2c3715SXin Li /** \returns the concatenation of a linear transformation \a l with the rotation \a r */ 75*bf2c3715SXin Li template<typename OtherDerived> friend 76*bf2c3715SXin Li EIGEN_DEVICE_FUNC inline RotationMatrixType operator*(const EigenBase<OtherDerived>& l, const Derived& r) 77*bf2c3715SXin Li { return l.derived() * r.toRotationMatrix(); } 78*bf2c3715SXin Li 79*bf2c3715SXin Li /** \returns the concatenation of a scaling \a l with the rotation \a r */ 80*bf2c3715SXin Li EIGEN_DEVICE_FUNC friend inline Transform<Scalar,Dim,Affine> operator*(const DiagonalMatrix<Scalar,Dim>& l, const Derived& r) 81*bf2c3715SXin Li { 82*bf2c3715SXin Li Transform<Scalar,Dim,Affine> res(r); 83*bf2c3715SXin Li res.linear().applyOnTheLeft(l); 84*bf2c3715SXin Li return res; 85*bf2c3715SXin Li } 86*bf2c3715SXin Li 87*bf2c3715SXin Li /** \returns the concatenation of the rotation \c *this with a transformation \a t */ 88*bf2c3715SXin Li template<int Mode, int Options> 89*bf2c3715SXin Li EIGEN_DEVICE_FUNC inline Transform<Scalar,Dim,Mode> operator*(const Transform<Scalar,Dim,Mode,Options>& t) const 90*bf2c3715SXin Li { return toRotationMatrix() * t; } 91*bf2c3715SXin Li 92*bf2c3715SXin Li template<typename OtherVectorType> _transformVector(const OtherVectorType & v)93*bf2c3715SXin Li EIGEN_DEVICE_FUNC inline VectorType _transformVector(const OtherVectorType& v) const 94*bf2c3715SXin Li { return toRotationMatrix() * v; } 95*bf2c3715SXin Li }; 96*bf2c3715SXin Li 97*bf2c3715SXin Li namespace internal { 98*bf2c3715SXin Li 99*bf2c3715SXin Li // implementation of the generic product rotation * matrix 100*bf2c3715SXin Li template<typename RotationDerived, typename MatrixType> 101*bf2c3715SXin Li struct rotation_base_generic_product_selector<RotationDerived,MatrixType,false> 102*bf2c3715SXin Li { 103*bf2c3715SXin Li enum { Dim = RotationDerived::Dim }; 104*bf2c3715SXin Li typedef Matrix<typename RotationDerived::Scalar,Dim,Dim> ReturnType; 105*bf2c3715SXin Li EIGEN_DEVICE_FUNC static inline ReturnType run(const RotationDerived& r, const MatrixType& m) 106*bf2c3715SXin Li { return r.toRotationMatrix() * m; } 107*bf2c3715SXin Li }; 108*bf2c3715SXin Li 109*bf2c3715SXin Li template<typename RotationDerived, typename Scalar, int Dim, int MaxDim> 110*bf2c3715SXin Li struct rotation_base_generic_product_selector< RotationDerived, DiagonalMatrix<Scalar,Dim,MaxDim>, false > 111*bf2c3715SXin Li { 112*bf2c3715SXin Li typedef Transform<Scalar,Dim,Affine> ReturnType; 113*bf2c3715SXin Li EIGEN_DEVICE_FUNC static inline ReturnType run(const RotationDerived& r, const DiagonalMatrix<Scalar,Dim,MaxDim>& m) 114*bf2c3715SXin Li { 115*bf2c3715SXin Li ReturnType res(r); 116*bf2c3715SXin Li res.linear() *= m; 117*bf2c3715SXin Li return res; 118*bf2c3715SXin Li } 119*bf2c3715SXin Li }; 120*bf2c3715SXin Li 121*bf2c3715SXin Li template<typename RotationDerived,typename OtherVectorType> 122*bf2c3715SXin Li struct rotation_base_generic_product_selector<RotationDerived,OtherVectorType,true> 123*bf2c3715SXin Li { 124*bf2c3715SXin Li enum { Dim = RotationDerived::Dim }; 125*bf2c3715SXin Li typedef Matrix<typename RotationDerived::Scalar,Dim,1> ReturnType; 126*bf2c3715SXin Li EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE ReturnType run(const RotationDerived& r, const OtherVectorType& v) 127*bf2c3715SXin Li { 128*bf2c3715SXin Li return r._transformVector(v); 129*bf2c3715SXin Li } 130*bf2c3715SXin Li }; 131*bf2c3715SXin Li 132*bf2c3715SXin Li } // end namespace internal 133*bf2c3715SXin Li 134*bf2c3715SXin Li /** \geometry_module 135*bf2c3715SXin Li * 136*bf2c3715SXin Li * \brief Constructs a Dim x Dim rotation matrix from the rotation \a r 137*bf2c3715SXin Li */ 138*bf2c3715SXin Li template<typename _Scalar, int _Rows, int _Cols, int _Storage, int _MaxRows, int _MaxCols> 139*bf2c3715SXin Li template<typename OtherDerived> 140*bf2c3715SXin Li EIGEN_DEVICE_FUNC Matrix<_Scalar, _Rows, _Cols, _Storage, _MaxRows, _MaxCols> 141*bf2c3715SXin Li ::Matrix(const RotationBase<OtherDerived,ColsAtCompileTime>& r) 142*bf2c3715SXin Li { 143*bf2c3715SXin Li EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Matrix,int(OtherDerived::Dim),int(OtherDerived::Dim)) 144*bf2c3715SXin Li *this = r.toRotationMatrix(); 145*bf2c3715SXin Li } 146*bf2c3715SXin Li 147*bf2c3715SXin Li /** \geometry_module 148*bf2c3715SXin Li * 149*bf2c3715SXin Li * \brief Set a Dim x Dim rotation matrix from the rotation \a r 150*bf2c3715SXin Li */ 151*bf2c3715SXin Li template<typename _Scalar, int _Rows, int _Cols, int _Storage, int _MaxRows, int _MaxCols> 152*bf2c3715SXin Li template<typename OtherDerived> 153*bf2c3715SXin Li EIGEN_DEVICE_FUNC Matrix<_Scalar, _Rows, _Cols, _Storage, _MaxRows, _MaxCols>& 154*bf2c3715SXin Li Matrix<_Scalar, _Rows, _Cols, _Storage, _MaxRows, _MaxCols> 155*bf2c3715SXin Li ::operator=(const RotationBase<OtherDerived,ColsAtCompileTime>& r) 156*bf2c3715SXin Li { 157*bf2c3715SXin Li EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Matrix,int(OtherDerived::Dim),int(OtherDerived::Dim)) 158*bf2c3715SXin Li return *this = r.toRotationMatrix(); 159*bf2c3715SXin Li } 160*bf2c3715SXin Li 161*bf2c3715SXin Li namespace internal { 162*bf2c3715SXin Li 163*bf2c3715SXin Li /** \internal 164*bf2c3715SXin Li * 165*bf2c3715SXin Li * Helper function to return an arbitrary rotation object to a rotation matrix. 166*bf2c3715SXin Li * 167*bf2c3715SXin Li * \tparam Scalar the numeric type of the matrix coefficients 168*bf2c3715SXin Li * \tparam Dim the dimension of the current space 169*bf2c3715SXin Li * 170*bf2c3715SXin Li * It returns a Dim x Dim fixed size matrix. 171*bf2c3715SXin Li * 172*bf2c3715SXin Li * Default specializations are provided for: 173*bf2c3715SXin Li * - any scalar type (2D), 174*bf2c3715SXin Li * - any matrix expression, 175*bf2c3715SXin Li * - any type based on RotationBase (e.g., Quaternion, AngleAxis, Rotation2D) 176*bf2c3715SXin Li * 177*bf2c3715SXin Li * Currently toRotationMatrix is only used by Transform. 178*bf2c3715SXin Li * 179*bf2c3715SXin Li * \sa class Transform, class Rotation2D, class Quaternion, class AngleAxis 180*bf2c3715SXin Li */ 181*bf2c3715SXin Li template<typename Scalar, int Dim> 182*bf2c3715SXin Li EIGEN_DEVICE_FUNC static inline Matrix<Scalar,2,2> toRotationMatrix(const Scalar& s) 183*bf2c3715SXin Li { 184*bf2c3715SXin Li EIGEN_STATIC_ASSERT(Dim==2,YOU_MADE_A_PROGRAMMING_MISTAKE) 185*bf2c3715SXin Li return Rotation2D<Scalar>(s).toRotationMatrix(); 186*bf2c3715SXin Li } 187*bf2c3715SXin Li 188*bf2c3715SXin Li template<typename Scalar, int Dim, typename OtherDerived> 189*bf2c3715SXin Li EIGEN_DEVICE_FUNC static inline Matrix<Scalar,Dim,Dim> toRotationMatrix(const RotationBase<OtherDerived,Dim>& r) 190*bf2c3715SXin Li { 191*bf2c3715SXin Li return r.toRotationMatrix(); 192*bf2c3715SXin Li } 193*bf2c3715SXin Li 194*bf2c3715SXin Li template<typename Scalar, int Dim, typename OtherDerived> 195*bf2c3715SXin Li EIGEN_DEVICE_FUNC static inline const MatrixBase<OtherDerived>& toRotationMatrix(const MatrixBase<OtherDerived>& mat) 196*bf2c3715SXin Li { 197*bf2c3715SXin Li EIGEN_STATIC_ASSERT(OtherDerived::RowsAtCompileTime==Dim && OtherDerived::ColsAtCompileTime==Dim, 198*bf2c3715SXin Li YOU_MADE_A_PROGRAMMING_MISTAKE) 199*bf2c3715SXin Li return mat; 200*bf2c3715SXin Li } 201*bf2c3715SXin Li 202*bf2c3715SXin Li } // end namespace internal 203*bf2c3715SXin Li 204*bf2c3715SXin Li } // end namespace Eigen 205*bf2c3715SXin Li 206*bf2c3715SXin Li #endif // EIGEN_ROTATIONBASE_H 207