diff options
author | Gael Guennebaud <g.gael@free.fr> | 2008-08-30 20:11:04 +0000 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2008-08-30 20:11:04 +0000 |
commit | 6ba991aa3a2ddd1a1ed1d64956aeab5cab680e54 (patch) | |
tree | f7f2aef74c7483bea393f717e08096d57b52e820 /Eigen | |
parent | 027ee14f31d98e9759a93d4c4f1bf1f2880f200a (diff) |
* added a RotationBase class following the CRT pattern
This allow code factorization and generic template specialization
of functions
* added any_rotation * {Translation,Scaling,Transform} products methods
* rewrite of the actually broken ToRoationMatrix helper class to
a global ei_toRotationMatrix function.
Diffstat (limited to 'Eigen')
-rw-r--r-- | Eigen/Geometry | 2 | ||||
-rw-r--r-- | Eigen/src/Geometry/AngleAxis.h | 11 | ||||
-rw-r--r-- | Eigen/src/Geometry/Quaternion.h | 10 | ||||
-rw-r--r-- | Eigen/src/Geometry/Rotation.h | 150 | ||||
-rw-r--r-- | Eigen/src/Geometry/Scaling.h | 4 | ||||
-rw-r--r-- | Eigen/src/Geometry/Transform.h | 26 | ||||
-rw-r--r-- | Eigen/src/Geometry/Translation.h | 4 |
7 files changed, 129 insertions, 78 deletions
diff --git a/Eigen/Geometry b/Eigen/Geometry index ab3a9b9d6..3bb4c8801 100644 --- a/Eigen/Geometry +++ b/Eigen/Geometry @@ -28,9 +28,9 @@ namespace Eigen { #include "src/Array/PartialRedux.h" #include "src/Geometry/OrthoMethods.h" +#include "src/Geometry/Rotation.h" #include "src/Geometry/Quaternion.h" #include "src/Geometry/AngleAxis.h" -#include "src/Geometry/Rotation.h" #include "src/Geometry/Transform.h" #include "src/Geometry/Translation.h" #include "src/Geometry/Scaling.h" diff --git a/Eigen/src/Geometry/AngleAxis.h b/Eigen/src/Geometry/AngleAxis.h index 502cbd0ec..0d43b277e 100644 --- a/Eigen/src/Geometry/AngleAxis.h +++ b/Eigen/src/Geometry/AngleAxis.h @@ -46,9 +46,18 @@ * * \sa class Quaternion, class Transform, MatrixBase::UnitX() */ + +template<typename _Scalar> struct ei_traits<AngleAxis<_Scalar> > +{ + typedef _Scalar Scalar; +}; + template<typename _Scalar> -class AngleAxis +class AngleAxis : public RotationBase<AngleAxis<_Scalar>,3> { + typedef RotationBase<AngleAxis<_Scalar>,3> Base; + using Base::operator*; + public: enum { Dim = 3 }; /** the scalar type of the coefficients */ diff --git a/Eigen/src/Geometry/Quaternion.h b/Eigen/src/Geometry/Quaternion.h index 483d4c0d7..fc1537711 100644 --- a/Eigen/src/Geometry/Quaternion.h +++ b/Eigen/src/Geometry/Quaternion.h @@ -51,9 +51,17 @@ struct ei_quaternion_assign_impl; * * \sa class AngleAxis, class Transform */ + +template<typename _Scalar> struct ei_traits<Quaternion<_Scalar> > +{ + typedef _Scalar Scalar; +}; + template<typename _Scalar> -class Quaternion +class Quaternion : public RotationBase<Quaternion<_Scalar>,3> { + typedef RotationBase<Quaternion<_Scalar>,3> Base; + using Base::operator*; typedef Matrix<_Scalar, 4, 1> Coefficients; Coefficients m_coeffs; diff --git a/Eigen/src/Geometry/Rotation.h b/Eigen/src/Geometry/Rotation.h index 9ce6e71ca..696fcdd4e 100644 --- a/Eigen/src/Geometry/Rotation.h +++ b/Eigen/src/Geometry/Rotation.h @@ -28,79 +28,42 @@ // this file aims to contains the various representations of rotation/orientation // in 2D and 3D space excepted Matrix and Quaternion. -/** \internal - * - * \class ToRotationMatrix - * - * \brief Template static struct to convert any rotation representation to a matrix form - * - * \param Scalar the numeric type of the matrix coefficients - * \param Dim the dimension of the current space - * \param RotationType the input type of the rotation +/** \class RotationBase * - * This class defines a single static member with the following prototype: - * \code - * static <MatrixExpression> convert(const RotationType& r); - * \endcode - * where \c <MatrixExpression> must be a fixed-size matrix expression of size Dim x Dim and - * coefficient type Scalar. - * - * Default specializations are provided for: - * - any scalar type (2D), - * - any matrix expression, - * - Quaternion, - * - AngleAxis. - * - * Currently ToRotationMatrix is only used by Transform. - * - * \sa class Transform, class Rotation2D, class Quaternion, class AngleAxis + * \brief Common base class for compact rotation representations * + * \param Derived is the derived type, i.e., a rotation type + * \param _Dim the dimension of the space */ -template<typename Scalar, int Dim, typename RotationType> -struct ToRotationMatrix; - -// 2D rotation to matrix -template<typename Scalar, typename OtherScalarType> -struct ToRotationMatrix<Scalar, 2, OtherScalarType> +template<typename Derived, int _Dim> +class RotationBase { - inline static Matrix<Scalar,2,2> convert(const OtherScalarType& r) - { return Rotation2D<Scalar>(r).toRotationMatrix(); } -}; - -// 2D rotation to rotation matrix -template<typename Scalar, typename OtherScalarType> -struct ToRotationMatrix<Scalar, 2, Rotation2D<OtherScalarType> > -{ - inline static Matrix<Scalar,2,2> convert(const Rotation2D<OtherScalarType>& r) - { return Rotation2D<Scalar>(r).toRotationMatrix(); } -}; - -// quaternion to rotation matrix -template<typename Scalar, typename OtherScalarType> -struct ToRotationMatrix<Scalar, 3, Quaternion<OtherScalarType> > -{ - inline static Matrix<Scalar,3,3> convert(const Quaternion<OtherScalarType>& q) - { return q.toRotationMatrix(); } -}; - -// angle axis to rotation matrix -template<typename Scalar, typename OtherScalarType> -struct ToRotationMatrix<Scalar, 3, AngleAxis<OtherScalarType> > -{ - inline static Matrix<Scalar,3,3> convert(const AngleAxis<OtherScalarType>& aa) - { return aa.toRotationMatrix(); } -}; - -// matrix xpr to matrix xpr -template<typename Scalar, int Dim, typename OtherDerived> -struct ToRotationMatrix<Scalar, Dim, MatrixBase<OtherDerived> > -{ - inline static const MatrixBase<OtherDerived>& convert(const MatrixBase<OtherDerived>& mat) - { - EIGEN_STATIC_ASSERT(OtherDerived::RowsAtCompileTime==Dim && OtherDerived::ColsAtCompileTime==Dim, - you_did_a_programming_error); - return mat; - } + public: + enum { Dim = _Dim }; + /** the scalar type of the coefficients */ + typedef typename ei_traits<Derived>::Scalar Scalar; + + /** corresponding linear transformation matrix type */ + typedef Matrix<Scalar,Dim,Dim> RotationMatrixType; + + inline const Derived& derived() const { return *static_cast<const Derived*>(this); } + inline Derived& derived() { return *static_cast<Derived*>(this); } + + /** \returns an equivalent rotation matrix */ + inline RotationMatrixType toRotationMatrix() const { return derived().toRotationMatrix(); } + + /** \returns the concatenation of the rotation \c *this with a translation \a t */ + inline Transform<Scalar,Dim> operator*(const Translation<Scalar,Dim>& t) const + { return toRotationMatrix() * t; } + + /** \returns the concatenation of the rotation \c *this with a scaling \a s */ + inline RotationMatrixType operator*(const Scaling<Scalar,Dim>& s) const + { return toRotationMatrix() * s; } + + /** \returns the concatenation of the rotation \c *this with an affine transformation \a t */ + inline Transform<Scalar,Dim> operator*(const Transform<Scalar,Dim>& t) const + { return toRotationMatrix() * t; } + }; /** \geometry_module \ingroup GeometryModule @@ -119,9 +82,17 @@ struct ToRotationMatrix<Scalar, Dim, MatrixBase<OtherDerived> > * * \sa class Quaternion, class Transform */ +template<typename _Scalar> struct ei_traits<Rotation2D<_Scalar> > +{ + typedef _Scalar Scalar; +}; + template<typename _Scalar> -class Rotation2D +class Rotation2D : public RotationBase<Rotation2D<_Scalar>,2> { + typedef RotationBase<Rotation2D<_Scalar>,2> Base; + using Base::operator*; + public: enum { Dim = 2 }; /** the scalar type of the coefficients */ @@ -206,4 +177,43 @@ Rotation2D<Scalar>::toRotationMatrix(void) const return (Matrix2() << cosA, -sinA, sinA, cosA).finished(); } +/** \internal + * + * Helper function to return an arbitrary rotation object to a rotation matrix. + * + * \param Scalar the numeric type of the matrix coefficients + * \param Dim the dimension of the current space + * + * It returns a Dim x Dim fixed size matrix. + * + * Default specializations are provided for: + * - any scalar type (2D), + * - any matrix expression, + * - any type based on RotationBase (e.g., Quaternion, AngleAxis, Rotation2D) + * + * Currently ei_toRotationMatrix is only used by Transform. + * + * \sa class Transform, class Rotation2D, class Quaternion, class AngleAxis + */ +template<typename Scalar, int Dim> +inline static Matrix<Scalar,2,2> ei_toRotationMatrix(const Scalar& s) +{ + EIGEN_STATIC_ASSERT(Dim==2,you_did_a_programming_error); + return Rotation2D<Scalar>(s).toRotationMatrix(); +} + +template<typename Scalar, int Dim, typename OtherDerived> +inline static Matrix<Scalar,Dim,Dim> ei_toRotationMatrix(const RotationBase<OtherDerived,Dim>& r) +{ + return r.toRotationMatrix(); +} + +template<typename Scalar, int Dim, typename OtherDerived> +inline static const MatrixBase<OtherDerived>& ei_toRotationMatrix(const MatrixBase<OtherDerived>& mat) +{ + EIGEN_STATIC_ASSERT(OtherDerived::RowsAtCompileTime==Dim && OtherDerived::ColsAtCompileTime==Dim, + you_did_a_programming_error); + return mat; +} + #endif // EIGEN_ROTATION_H diff --git a/Eigen/src/Geometry/Scaling.h b/Eigen/src/Geometry/Scaling.h index 73938ac8b..4712b7d94 100644 --- a/Eigen/src/Geometry/Scaling.h +++ b/Eigen/src/Geometry/Scaling.h @@ -105,6 +105,10 @@ public: friend inline LinearMatrixType operator* (const LinearMatrixType& other, const Scaling& s) { return other * s.coeffs().asDiagonal(); } + template<typename Derived> + inline LinearMatrixType operator*(const RotationBase<Derived,Dim>& r) const + { return *this * r.toRotationMatrix(); } + /** Applies scaling to vector */ inline VectorType operator* (const VectorType& other) const { return coeffs().asDiagonal() * other; } diff --git a/Eigen/src/Geometry/Transform.h b/Eigen/src/Geometry/Transform.h index 1a60fe0ab..da457fc38 100644 --- a/Eigen/src/Geometry/Transform.h +++ b/Eigen/src/Geometry/Transform.h @@ -218,6 +218,13 @@ public: return res; } +// template<typename Derived> +// inline Transform& operator=(const Rotation<Derived,Dim>& t); + template<typename Derived> + inline Transform& operator*=(const RotationBase<Derived,Dim>& r) { return rotate(r.toRotationMatrix()); } + template<typename Derived> + inline Transform operator*(const RotationBase<Derived,Dim>& r) const; + LinearMatrixType extractRotation(TransformTraits traits = GenericAffine) const; template<typename PositionDerived, typename OrientationType, typename ScaleDerived> @@ -349,7 +356,7 @@ Transform<Scalar,Dim>::pretranslate(const MatrixBase<OtherDerived> &other) * to \c *this and returns a reference to \c *this. * * The template parameter \a RotationType is the type of the rotation which - * must be registered by ToRotationMatrix<>. + * must be known by ei_toRotationMatrix<>. * * Natively supported types includes: * - any scalar (2D), @@ -360,14 +367,14 @@ Transform<Scalar,Dim>::pretranslate(const MatrixBase<OtherDerived> &other) * This mechanism is easily extendable to support user types such as Euler angles, * or a pair of Quaternion for 4D rotations. * - * \sa rotate(Scalar), class Quaternion, class AngleAxis, class ToRotationMatrix, prerotate(RotationType) + * \sa rotate(Scalar), class Quaternion, class AngleAxis, prerotate(RotationType) */ template<typename Scalar, int Dim> template<typename RotationType> Transform<Scalar,Dim>& Transform<Scalar,Dim>::rotate(const RotationType& rotation) { - linear() *= ToRotationMatrix<Scalar,Dim,RotationType>::convert(rotation); + linear() *= ei_toRotationMatrix<Scalar,Dim>(rotation); return *this; } @@ -383,7 +390,7 @@ template<typename RotationType> Transform<Scalar,Dim>& Transform<Scalar,Dim>::prerotate(const RotationType& rotation) { - m_matrix.template block<Dim,HDim>(0,0) = ToRotationMatrix<Scalar,Dim,RotationType>::convert(rotation) + m_matrix.template block<Dim,HDim>(0,0) = ei_toRotationMatrix<Scalar,Dim>(rotation) * m_matrix.template block<Dim,HDim>(0,0); return *this; } @@ -454,6 +461,15 @@ inline Transform<Scalar,Dim> Transform<Scalar,Dim>::operator*(const ScalingType& return res; } +template<typename Scalar, int Dim> +template<typename Derived> +inline Transform<Scalar,Dim> Transform<Scalar,Dim>::operator*(const RotationBase<Derived,Dim>& r) const +{ + Transform res = *this; + res.rotate(r.derived()); + return res; +} + /*************************** *** Specialial functions *** ***************************/ @@ -511,7 +527,7 @@ Transform<Scalar,Dim>& Transform<Scalar,Dim>::fromPositionOrientationScale(const MatrixBase<PositionDerived> &position, const OrientationType& orientation, const MatrixBase<ScaleDerived> &scale) { - linear() = ToRotationMatrix<Scalar,Dim,OrientationType>::convert(orientation); + linear() = ei_toRotationMatrix<Scalar,Dim>(orientation); linear() *= scale.asDiagonal(); translation() = position; m_matrix(Dim,Dim) = 1.; diff --git a/Eigen/src/Geometry/Translation.h b/Eigen/src/Geometry/Translation.h index b65aca9eb..f35670546 100644 --- a/Eigen/src/Geometry/Translation.h +++ b/Eigen/src/Geometry/Translation.h @@ -93,6 +93,10 @@ public: /** Concatenates a translation and a linear transformation */ inline TransformType operator* (const LinearMatrixType& linear) const; + template<typename Derived> + inline TransformType operator*(const RotationBase<Derived,Dim>& r) const + { return *this * r.toRotationMatrix(); } + /** Concatenates a linear transformation and a translation */ // its a nightmare to define a templated friend function outside its declaration friend inline TransformType operator* (const LinearMatrixType& linear, const Translation& t) |