RotationBase.h 7.9 KB

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