RotationBase.h
Go to the documentation of this file.
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
00005 //
00006 // Eigen is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 3 of the License, or (at your option) any later version.
00010 //
00011 // Alternatively, you can redistribute it and/or
00012 // modify it under the terms of the GNU General Public License as
00013 // published by the Free Software Foundation; either version 2 of
00014 // the License, or (at your option) any later version.
00015 //
00016 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
00017 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00018 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
00019 // GNU General Public License for more details.
00020 //
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License and a copy of the GNU General Public License along with
00023 // Eigen. If not, see <http://www.gnu.org/licenses/>.
00024 
00025 #ifndef EIGEN_ROTATIONBASE_H
00026 #define EIGEN_ROTATIONBASE_H
00027 
00028 namespace Eigen { 
00029 
00030 // forward declaration
00031 namespace internal {
00032 template<typename RotationDerived, typename MatrixType, bool IsVector=MatrixType::IsVectorAtCompileTime>
00033 struct rotation_base_generic_product_selector;
00034 }
00035 
00043 template<typename Derived, int _Dim>
00044 class RotationBase
00045 {
00046   public:
00047     enum { Dim = _Dim };
00049     typedef typename internal::traits<Derived>::Scalar Scalar;
00050 
00052     typedef Matrix<Scalar,Dim,Dim> RotationMatrixType;
00053     typedef Matrix<Scalar,Dim,1> VectorType;
00054 
00055   public:
00056     inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
00057     inline Derived& derived() { return *static_cast<Derived*>(this); }
00058 
00060     inline RotationMatrixType toRotationMatrix() const { return derived().toRotationMatrix(); }
00061 
00065     inline RotationMatrixType matrix() const { return derived().toRotationMatrix(); }
00066 
00068     inline Derived inverse() const { return derived().inverse(); }
00069 
00071     inline Transform<Scalar,Dim,Isometry> operator*(const Translation<Scalar,Dim>& t) const
00072     { return Transform<Scalar,Dim,Isometry>(*this) * t; }
00073 
00075     inline RotationMatrixType operator*(const UniformScaling<Scalar>& s) const
00076     { return toRotationMatrix() * s.factor(); }
00077 
00084     template<typename OtherDerived>
00085     EIGEN_STRONG_INLINE typename internal::rotation_base_generic_product_selector<Derived,OtherDerived,OtherDerived::IsVectorAtCompileTime>::ReturnType
00086     operator*(const EigenBase<OtherDerived>& e) const
00087     { return internal::rotation_base_generic_product_selector<Derived,OtherDerived>::run(derived(), e.derived()); }
00088 
00090     template<typename OtherDerived> friend
00091     inline RotationMatrixType operator*(const EigenBase<OtherDerived>& l, const Derived& r)
00092     { return l.derived() * r.toRotationMatrix(); }
00093 
00095     friend inline Transform<Scalar,Dim,Affine> operator*(const DiagonalMatrix<Scalar,Dim>& l, const Derived& r)
00096     { 
00097       Transform<Scalar,Dim,Affine> res(r);
00098       res.linear().applyOnTheLeft(l);
00099       return res;
00100     }
00101 
00103     template<int Mode, int Options>
00104     inline Transform<Scalar,Dim,Mode> operator*(const Transform<Scalar,Dim,Mode,Options>& t) const
00105     { return toRotationMatrix() * t; }
00106 
00107     template<typename OtherVectorType>
00108     inline VectorType _transformVector(const OtherVectorType& v) const
00109     { return toRotationMatrix() * v; }
00110 };
00111 
00112 namespace internal {
00113 
00114 // implementation of the generic product rotation * matrix
00115 template<typename RotationDerived, typename MatrixType>
00116 struct rotation_base_generic_product_selector<RotationDerived,MatrixType,false>
00117 {
00118   enum { Dim = RotationDerived::Dim };
00119   typedef Matrix<typename RotationDerived::Scalar,Dim,Dim> ReturnType;
00120   static inline ReturnType run(const RotationDerived& r, const MatrixType& m)
00121   { return r.toRotationMatrix() * m; }
00122 };
00123 
00124 template<typename RotationDerived, typename Scalar, int Dim, int MaxDim>
00125 struct rotation_base_generic_product_selector< RotationDerived, DiagonalMatrix<Scalar,Dim,MaxDim>, false >
00126 {
00127   typedef Transform<Scalar,Dim,Affine> ReturnType;
00128   static inline ReturnType run(const RotationDerived& r, const DiagonalMatrix<Scalar,Dim,MaxDim>& m)
00129   {
00130     ReturnType res(r);
00131     res.linear() *= m;
00132     return res;
00133   }
00134 };
00135 
00136 template<typename RotationDerived,typename OtherVectorType>
00137 struct rotation_base_generic_product_selector<RotationDerived,OtherVectorType,true>
00138 {
00139   enum { Dim = RotationDerived::Dim };
00140   typedef Matrix<typename RotationDerived::Scalar,Dim,1> ReturnType;
00141   static EIGEN_STRONG_INLINE ReturnType run(const RotationDerived& r, const OtherVectorType& v)
00142   {
00143     return r._transformVector(v);
00144   }
00145 };
00146 
00147 } // end namespace internal
00148 
00153 template<typename _Scalar, int _Rows, int _Cols, int _Storage, int _MaxRows, int _MaxCols>
00154 template<typename OtherDerived>
00155 Matrix<_Scalar, _Rows, _Cols, _Storage, _MaxRows, _MaxCols>
00156 ::Matrix(const RotationBase<OtherDerived,ColsAtCompileTime>& r)
00157 {
00158   EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Matrix,int(OtherDerived::Dim),int(OtherDerived::Dim))
00159   *this = r.toRotationMatrix();
00160 }
00161 
00166 template<typename _Scalar, int _Rows, int _Cols, int _Storage, int _MaxRows, int _MaxCols>
00167 template<typename OtherDerived>
00168 Matrix<_Scalar, _Rows, _Cols, _Storage, _MaxRows, _MaxCols>&
00169 Matrix<_Scalar, _Rows, _Cols, _Storage, _MaxRows, _MaxCols>
00170 ::operator=(const RotationBase<OtherDerived,ColsAtCompileTime>& r)
00171 {
00172   EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Matrix,int(OtherDerived::Dim),int(OtherDerived::Dim))
00173   return *this = r.toRotationMatrix();
00174 }
00175 
00176 namespace internal {
00177 
00196 template<typename Scalar, int Dim>
00197 static inline Matrix<Scalar,2,2> toRotationMatrix(const Scalar& s)
00198 {
00199   EIGEN_STATIC_ASSERT(Dim==2,YOU_MADE_A_PROGRAMMING_MISTAKE)
00200   return Rotation2D<Scalar>(s).toRotationMatrix();
00201 }
00202 
00203 template<typename Scalar, int Dim, typename OtherDerived>
00204 static inline Matrix<Scalar,Dim,Dim> toRotationMatrix(const RotationBase<OtherDerived,Dim>& r)
00205 {
00206   return r.toRotationMatrix();
00207 }
00208 
00209 template<typename Scalar, int Dim, typename OtherDerived>
00210 static inline const MatrixBase<OtherDerived>& toRotationMatrix(const MatrixBase<OtherDerived>& mat)
00211 {
00212   EIGEN_STATIC_ASSERT(OtherDerived::RowsAtCompileTime==Dim && OtherDerived::ColsAtCompileTime==Dim,
00213     YOU_MADE_A_PROGRAMMING_MISTAKE)
00214   return mat;
00215 }
00216 
00217 } // end namespace internal
00218 
00219 } // end namespace Eigen
00220 
00221 #endif // EIGEN_ROTATIONBASE_H