Transform.h
Go to the documentation of this file.
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra. Eigen itself is part of the KDE project.
00003 //
00004 // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
00005 // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
00006 //
00007 // Eigen is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU Lesser General Public
00009 // License as published by the Free Software Foundation; either
00010 // version 3 of the License, or (at your option) any later version.
00011 //
00012 // Alternatively, you can redistribute it and/or
00013 // modify it under the terms of the GNU General Public License as
00014 // published by the Free Software Foundation; either version 2 of
00015 // the License, or (at your option) any later version.
00016 //
00017 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
00018 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00019 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
00020 // GNU General Public License for more details.
00021 //
00022 // You should have received a copy of the GNU Lesser General Public
00023 // License and a copy of the GNU General Public License along with
00024 // Eigen. If not, see <http://www.gnu.org/licenses/>.
00025 
00026 // no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway
00027 
00028 
00029 // Note that we have to pass Dim and HDim because it is not allowed to use a template
00030 // parameter to define a template specialization. To be more precise, in the following
00031 // specializations, it is not allowed to use Dim+1 instead of HDim.
00032 template< typename Other,
00033           int Dim,
00034           int HDim,
00035           int OtherRows=Other::RowsAtCompileTime,
00036           int OtherCols=Other::ColsAtCompileTime>
00037 struct ei_transform_product_impl;
00038 
00056 template<typename _Scalar, int _Dim>
00057 class Transform
00058 {
00059 public:
00060   EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_Dim==Dynamic ? Dynamic : (_Dim+1)*(_Dim+1))
00061   enum {
00062     Dim = _Dim,     
00063     HDim = _Dim+1   
00064   };
00066   typedef _Scalar Scalar;
00068   typedef Matrix<Scalar,HDim,HDim> MatrixType;
00070   typedef Matrix<Scalar,Dim,Dim> LinearMatrixType;
00072   typedef Block<MatrixType,Dim,Dim> LinearPart;
00074   typedef const Block<const MatrixType,Dim,Dim> ConstLinearPart;
00076   typedef Matrix<Scalar,Dim,1> VectorType;
00078   typedef Block<MatrixType,Dim,1> TranslationPart;
00080   typedef const Block<const MatrixType,Dim,1> ConstTranslationPart;
00082   typedef Translation<Scalar,Dim> TranslationType;
00084   typedef Scaling<Scalar,Dim> ScalingType;
00085 
00086 protected:
00087 
00088   MatrixType m_matrix;
00089 
00090 public:
00091 
00093   inline Transform() { }
00094 
00095   inline Transform(const Transform& other)
00096   {
00097     m_matrix = other.m_matrix;
00098   }
00099 
00100   inline explicit Transform(const TranslationType& t) { *this = t; }
00101   inline explicit Transform(const ScalingType& s) { *this = s; }
00102   template<typename Derived>
00103   inline explicit Transform(const RotationBase<Derived, Dim>& r) { *this = r; }
00104 
00105   inline Transform& operator=(const Transform& other)
00106   { m_matrix = other.m_matrix; return *this; }
00107 
00108   template<typename OtherDerived, bool BigMatrix> // MSVC 2005 will commit suicide if BigMatrix has a default value
00109   struct construct_from_matrix
00110   {
00111     static inline void run(Transform *transform, const MatrixBase<OtherDerived>& other)
00112     {
00113       transform->matrix() = other;
00114     }
00115   };
00116 
00117   template<typename OtherDerived> struct construct_from_matrix<OtherDerived, true>
00118   {
00119     static inline void run(Transform *transform, const MatrixBase<OtherDerived>& other)
00120     {
00121       transform->linear() = other;
00122       transform->translation().setZero();
00123       transform->matrix()(Dim,Dim) = Scalar(1);
00124       transform->matrix().template block<1,Dim>(Dim,0).setZero();
00125     }
00126   };
00127 
00129   template<typename OtherDerived>
00130   inline explicit Transform(const MatrixBase<OtherDerived>& other)
00131   {
00132     construct_from_matrix<OtherDerived, int(OtherDerived::RowsAtCompileTime) == Dim>::run(this, other);
00133   }
00134 
00136   template<typename OtherDerived>
00137   inline Transform& operator=(const MatrixBase<OtherDerived>& other)
00138   { m_matrix = other; return *this; }
00139 
00140   #ifdef EIGEN_QT_SUPPORT
00141   inline Transform(const QMatrix& other);
00142   inline Transform& operator=(const QMatrix& other);
00143   inline QMatrix toQMatrix(void) const;
00144   inline Transform(const QTransform& other);
00145   inline Transform& operator=(const QTransform& other);
00146   inline QTransform toQTransform(void) const;
00147   #endif
00148 
00151   inline Scalar operator() (int row, int col) const { return m_matrix(row,col); }
00154   inline Scalar& operator() (int row, int col) { return m_matrix(row,col); }
00155 
00157   inline const MatrixType& matrix() const { return m_matrix; }
00159   inline MatrixType& matrix() { return m_matrix; }
00160 
00162   inline ConstLinearPart linear() const { return m_matrix.template block<Dim,Dim>(0,0); }
00164   inline LinearPart linear() { return m_matrix.template block<Dim,Dim>(0,0); }
00165 
00167   inline ConstTranslationPart translation() const { return m_matrix.template block<Dim,1>(0,Dim); }
00169   inline TranslationPart translation() { return m_matrix.template block<Dim,1>(0,Dim); }
00170 
00178   // note: this function is defined here because some compilers cannot find the respective declaration
00179   template<typename OtherDerived>
00180   inline const typename ei_transform_product_impl<OtherDerived,_Dim,_Dim+1>::ResultType
00181   operator * (const MatrixBase<OtherDerived> &other) const
00182   { return ei_transform_product_impl<OtherDerived,Dim,HDim>::run(*this,other.derived()); }
00183 
00186   template<typename OtherDerived>
00187   friend inline const typename ProductReturnType<OtherDerived,MatrixType>::Type
00188   operator * (const MatrixBase<OtherDerived> &a, const Transform &b)
00189   { return a.derived() * b.matrix(); }
00190 
00192   inline const Transform
00193   operator * (const Transform& other) const
00194   { return Transform(m_matrix * other.matrix()); }
00195 
00197   void setIdentity() { m_matrix.setIdentity(); }
00198   static const typename MatrixType::IdentityReturnType Identity()
00199   {
00200     return MatrixType::Identity();
00201   }
00202 
00203   template<typename OtherDerived>
00204   inline Transform& scale(const MatrixBase<OtherDerived> &other);
00205 
00206   template<typename OtherDerived>
00207   inline Transform& prescale(const MatrixBase<OtherDerived> &other);
00208 
00209   inline Transform& scale(Scalar s);
00210   inline Transform& prescale(Scalar s);
00211 
00212   template<typename OtherDerived>
00213   inline Transform& translate(const MatrixBase<OtherDerived> &other);
00214 
00215   template<typename OtherDerived>
00216   inline Transform& pretranslate(const MatrixBase<OtherDerived> &other);
00217 
00218   template<typename RotationType>
00219   inline Transform& rotate(const RotationType& rotation);
00220 
00221   template<typename RotationType>
00222   inline Transform& prerotate(const RotationType& rotation);
00223 
00224   Transform& shear(Scalar sx, Scalar sy);
00225   Transform& preshear(Scalar sx, Scalar sy);
00226 
00227   inline Transform& operator=(const TranslationType& t);
00228   inline Transform& operator*=(const TranslationType& t) { return translate(t.vector()); }
00229   inline Transform operator*(const TranslationType& t) const;
00230 
00231   inline Transform& operator=(const ScalingType& t);
00232   inline Transform& operator*=(const ScalingType& s) { return scale(s.coeffs()); }
00233   inline Transform operator*(const ScalingType& s) const;
00234   friend inline Transform operator*(const LinearMatrixType& mat, const Transform& t)
00235   {
00236     Transform res = t;
00237     res.matrix().row(Dim) = t.matrix().row(Dim);
00238     res.matrix().template block<Dim,HDim>(0,0) = (mat * t.matrix().template block<Dim,HDim>(0,0)).lazy();
00239     return res;
00240   }
00241 
00242   template<typename Derived>
00243   inline Transform& operator=(const RotationBase<Derived,Dim>& r);
00244   template<typename Derived>
00245   inline Transform& operator*=(const RotationBase<Derived,Dim>& r) { return rotate(r.toRotationMatrix()); }
00246   template<typename Derived>
00247   inline Transform operator*(const RotationBase<Derived,Dim>& r) const;
00248 
00249   LinearMatrixType rotation() const;
00250   template<typename RotationMatrixType, typename ScalingMatrixType>
00251   void computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const;
00252   template<typename ScalingMatrixType, typename RotationMatrixType>
00253   void computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const;
00254 
00255   template<typename PositionDerived, typename OrientationType, typename ScaleDerived>
00256   Transform& fromPositionOrientationScale(const MatrixBase<PositionDerived> &position,
00257     const OrientationType& orientation, const MatrixBase<ScaleDerived> &scale);
00258 
00259   inline const MatrixType inverse(TransformTraits traits = Affine) const;
00260 
00262   const Scalar* data() const { return m_matrix.data(); }
00264   Scalar* data() { return m_matrix.data(); }
00265 
00271   template<typename NewScalarType>
00272   inline typename internal::cast_return_type<Transform,Transform<NewScalarType,Dim> >::type cast() const
00273   { return typename internal::cast_return_type<Transform,Transform<NewScalarType,Dim> >::type(*this); }
00274 
00276   template<typename OtherScalarType>
00277   inline explicit Transform(const Transform<OtherScalarType,Dim>& other)
00278   { m_matrix = other.matrix().template cast<Scalar>(); }
00279 
00284   bool isApprox(const Transform& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
00285   { return m_matrix.isApprox(other.m_matrix, prec); }
00286 
00287   #ifdef EIGEN_TRANSFORM_PLUGIN
00288   #include EIGEN_TRANSFORM_PLUGIN
00289   #endif
00290 
00291 protected:
00292 
00293 };
00294 
00296 typedef Transform<float,2> Transform2f;
00298 typedef Transform<float,3> Transform3f;
00300 typedef Transform<double,2> Transform2d;
00302 typedef Transform<double,3> Transform3d;
00303 
00304 /**************************
00305 *** Optional QT support ***
00306 **************************/
00307 
00308 #ifdef EIGEN_QT_SUPPORT
00309 
00313 template<typename Scalar, int Dim>
00314 Transform<Scalar,Dim>::Transform(const QMatrix& other)
00315 {
00316   *this = other;
00317 }
00318 
00323 template<typename Scalar, int Dim>
00324 Transform<Scalar,Dim>& Transform<Scalar,Dim>::operator=(const QMatrix& other)
00325 {
00326   EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00327   m_matrix << other.m11(), other.m21(), other.dx(),
00328               other.m12(), other.m22(), other.dy(),
00329               0, 0, 1;
00330    return *this;
00331 }
00332 
00339 template<typename Scalar, int Dim>
00340 QMatrix Transform<Scalar,Dim>::toQMatrix(void) const
00341 {
00342   EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00343   return QMatrix(m_matrix.coeff(0,0), m_matrix.coeff(1,0),
00344                  m_matrix.coeff(0,1), m_matrix.coeff(1,1),
00345                  m_matrix.coeff(0,2), m_matrix.coeff(1,2));
00346 }
00347 
00352 template<typename Scalar, int Dim>
00353 Transform<Scalar,Dim>::Transform(const QTransform& other)
00354 {
00355   *this = other;
00356 }
00357 
00362 template<typename Scalar, int Dim>
00363 Transform<Scalar,Dim>& Transform<Scalar,Dim>::operator=(const QTransform& other)
00364 {
00365   EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00366   m_matrix << other.m11(), other.m21(), other.dx(),
00367               other.m12(), other.m22(), other.dy(),
00368               other.m13(), other.m23(), other.m33();
00369    return *this;
00370 }
00371 
00376 template<typename Scalar, int Dim>
00377 QTransform Transform<Scalar,Dim>::toQTransform(void) const
00378 {
00379   EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00380   return QTransform(m_matrix.coeff(0,0), m_matrix.coeff(1,0), m_matrix.coeff(2,0),
00381                     m_matrix.coeff(0,1), m_matrix.coeff(1,1), m_matrix.coeff(2,1),
00382                     m_matrix.coeff(0,2), m_matrix.coeff(1,2), m_matrix.coeff(2,2));
00383 }
00384 #endif
00385 
00386 /*********************
00387 *** Procedural API ***
00388 *********************/
00389 
00394 template<typename Scalar, int Dim>
00395 template<typename OtherDerived>
00396 Transform<Scalar,Dim>&
00397 Transform<Scalar,Dim>::scale(const MatrixBase<OtherDerived> &other)
00398 {
00399   EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
00400   linear() = (linear() * other.asDiagonal()).lazy();
00401   return *this;
00402 }
00403 
00408 template<typename Scalar, int Dim>
00409 inline Transform<Scalar,Dim>& Transform<Scalar,Dim>::scale(Scalar s)
00410 {
00411   linear() *= s;
00412   return *this;
00413 }
00414 
00419 template<typename Scalar, int Dim>
00420 template<typename OtherDerived>
00421 Transform<Scalar,Dim>&
00422 Transform<Scalar,Dim>::prescale(const MatrixBase<OtherDerived> &other)
00423 {
00424   EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
00425   m_matrix.template block<Dim,HDim>(0,0) = (other.asDiagonal() * m_matrix.template block<Dim,HDim>(0,0)).lazy();
00426   return *this;
00427 }
00428 
00433 template<typename Scalar, int Dim>
00434 inline Transform<Scalar,Dim>& Transform<Scalar,Dim>::prescale(Scalar s)
00435 {
00436   m_matrix.template corner<Dim,HDim>(TopLeft) *= s;
00437   return *this;
00438 }
00439 
00444 template<typename Scalar, int Dim>
00445 template<typename OtherDerived>
00446 Transform<Scalar,Dim>&
00447 Transform<Scalar,Dim>::translate(const MatrixBase<OtherDerived> &other)
00448 {
00449   EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
00450   translation() += linear() * other;
00451   return *this;
00452 }
00453 
00458 template<typename Scalar, int Dim>
00459 template<typename OtherDerived>
00460 Transform<Scalar,Dim>&
00461 Transform<Scalar,Dim>::pretranslate(const MatrixBase<OtherDerived> &other)
00462 {
00463   EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
00464   translation() += other;
00465   return *this;
00466 }
00467 
00485 template<typename Scalar, int Dim>
00486 template<typename RotationType>
00487 Transform<Scalar,Dim>&
00488 Transform<Scalar,Dim>::rotate(const RotationType& rotation)
00489 {
00490   linear() *= ei_toRotationMatrix<Scalar,Dim>(rotation);
00491   return *this;
00492 }
00493 
00501 template<typename Scalar, int Dim>
00502 template<typename RotationType>
00503 Transform<Scalar,Dim>&
00504 Transform<Scalar,Dim>::prerotate(const RotationType& rotation)
00505 {
00506   m_matrix.template block<Dim,HDim>(0,0) = ei_toRotationMatrix<Scalar,Dim>(rotation)
00507                                          * m_matrix.template block<Dim,HDim>(0,0);
00508   return *this;
00509 }
00510 
00516 template<typename Scalar, int Dim>
00517 Transform<Scalar,Dim>&
00518 Transform<Scalar,Dim>::shear(Scalar sx, Scalar sy)
00519 {
00520   EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00521   VectorType tmp = linear().col(0)*sy + linear().col(1);
00522   linear() << linear().col(0) + linear().col(1)*sx, tmp;
00523   return *this;
00524 }
00525 
00531 template<typename Scalar, int Dim>
00532 Transform<Scalar,Dim>&
00533 Transform<Scalar,Dim>::preshear(Scalar sx, Scalar sy)
00534 {
00535   EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00536   m_matrix.template block<Dim,HDim>(0,0) = LinearMatrixType(1, sx, sy, 1) * m_matrix.template block<Dim,HDim>(0,0);
00537   return *this;
00538 }
00539 
00540 /******************************************************
00541 *** Scaling, Translation and Rotation compatibility ***
00542 ******************************************************/
00543 
00544 template<typename Scalar, int Dim>
00545 inline Transform<Scalar,Dim>& Transform<Scalar,Dim>::operator=(const TranslationType& t)
00546 {
00547   linear().setIdentity();
00548   translation() = t.vector();
00549   m_matrix.template block<1,Dim>(Dim,0).setZero();
00550   m_matrix(Dim,Dim) = Scalar(1);
00551   return *this;
00552 }
00553 
00554 template<typename Scalar, int Dim>
00555 inline Transform<Scalar,Dim> Transform<Scalar,Dim>::operator*(const TranslationType& t) const
00556 {
00557   Transform res = *this;
00558   res.translate(t.vector());
00559   return res;
00560 }
00561 
00562 template<typename Scalar, int Dim>
00563 inline Transform<Scalar,Dim>& Transform<Scalar,Dim>::operator=(const ScalingType& s)
00564 {
00565   m_matrix.setZero();
00566   linear().diagonal() = s.coeffs();
00567   m_matrix.coeffRef(Dim,Dim) = Scalar(1);
00568   return *this;
00569 }
00570 
00571 template<typename Scalar, int Dim>
00572 inline Transform<Scalar,Dim> Transform<Scalar,Dim>::operator*(const ScalingType& s) const
00573 {
00574   Transform res = *this;
00575   res.scale(s.coeffs());
00576   return res;
00577 }
00578 
00579 template<typename Scalar, int Dim>
00580 template<typename Derived>
00581 inline Transform<Scalar,Dim>& Transform<Scalar,Dim>::operator=(const RotationBase<Derived,Dim>& r)
00582 {
00583   linear() = ei_toRotationMatrix<Scalar,Dim>(r);
00584   translation().setZero();
00585   m_matrix.template block<1,Dim>(Dim,0).setZero();
00586   m_matrix.coeffRef(Dim,Dim) = Scalar(1);
00587   return *this;
00588 }
00589 
00590 template<typename Scalar, int Dim>
00591 template<typename Derived>
00592 inline Transform<Scalar,Dim> Transform<Scalar,Dim>::operator*(const RotationBase<Derived,Dim>& r) const
00593 {
00594   Transform res = *this;
00595   res.rotate(r.derived());
00596   return res;
00597 }
00598 
00599 /************************
00600 *** Special functions ***
00601 ************************/
00602 
00610 template<typename Scalar, int Dim>
00611 typename Transform<Scalar,Dim>::LinearMatrixType
00612 Transform<Scalar,Dim>::rotation() const
00613 {
00614   LinearMatrixType result;
00615   computeRotationScaling(&result, (LinearMatrixType*)0);
00616   return result;
00617 }
00618 
00619 
00631 template<typename Scalar, int Dim>
00632 template<typename RotationMatrixType, typename ScalingMatrixType>
00633 void Transform<Scalar,Dim>::computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const
00634 {
00635   JacobiSVD<LinearMatrixType> svd(linear(), ComputeFullU|ComputeFullV);
00636   Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant(); // so x has absolute value 1
00637   Matrix<Scalar, Dim, 1> sv(svd.singularValues());
00638   sv.coeffRef(0) *= x;
00639   if(scaling)
00640   {
00641     scaling->noalias() = svd.matrixV() * sv.asDiagonal() * svd.matrixV().adjoint();
00642   }
00643   if(rotation)
00644   {
00645     LinearMatrixType m(svd.matrixU());
00646     m.col(0) /= x;
00647     rotation->noalias() = m * svd.matrixV().adjoint();
00648   }
00649 }
00650 
00662 template<typename Scalar, int Dim>
00663 template<typename ScalingMatrixType, typename RotationMatrixType>
00664 void Transform<Scalar,Dim>::computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const
00665 {
00666   JacobiSVD<LinearMatrixType> svd(linear(), ComputeFullU|ComputeFullV);
00667   Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant(); // so x has absolute value 1
00668   Matrix<Scalar, Dim, 1> sv(svd.singularValues());
00669   sv.coeffRef(0) *= x;
00670   if(scaling)
00671   {
00672     scaling->noalias() = svd.matrixU() * sv.asDiagonal() * svd.matrixU().adjoint();
00673   }
00674   if(rotation)
00675   {
00676     LinearMatrixType m(svd.matrixU());
00677     m.col(0) /= x;
00678     rotation->noalias() = m * svd.matrixV().adjoint();
00679   }
00680 }
00681 
00685 template<typename Scalar, int Dim>
00686 template<typename PositionDerived, typename OrientationType, typename ScaleDerived>
00687 Transform<Scalar,Dim>&
00688 Transform<Scalar,Dim>::fromPositionOrientationScale(const MatrixBase<PositionDerived> &position,
00689   const OrientationType& orientation, const MatrixBase<ScaleDerived> &scale)
00690 {
00691   linear() = ei_toRotationMatrix<Scalar,Dim>(orientation);
00692   linear() *= scale.asDiagonal();
00693   translation() = position;
00694   m_matrix.template block<1,Dim>(Dim,0).setZero();
00695   m_matrix(Dim,Dim) = Scalar(1);
00696   return *this;
00697 }
00698 
00718 template<typename Scalar, int Dim>
00719 inline const typename Transform<Scalar,Dim>::MatrixType
00720 Transform<Scalar,Dim>::inverse(TransformTraits traits) const
00721 {
00722   if (traits == Projective)
00723   {
00724     return m_matrix.inverse();
00725   }
00726   else
00727   {
00728     MatrixType res;
00729     if (traits == Affine)
00730     {
00731       res.template corner<Dim,Dim>(TopLeft) = linear().inverse();
00732     }
00733     else if (traits == Isometry)
00734     {
00735       res.template corner<Dim,Dim>(TopLeft) = linear().transpose();
00736     }
00737     else
00738     {
00739       ei_assert("invalid traits value in Transform::inverse()");
00740     }
00741     // translation and remaining parts
00742     res.template corner<Dim,1>(TopRight) = - res.template corner<Dim,Dim>(TopLeft) * translation();
00743     res.template corner<1,Dim>(BottomLeft).setZero();
00744     res.coeffRef(Dim,Dim) = Scalar(1);
00745     return res;
00746   }
00747 }
00748 
00749 /*****************************************************
00750 *** Specializations of operator* with a MatrixBase ***
00751 *****************************************************/
00752 
00753 template<typename Other, int Dim, int HDim>
00754 struct ei_transform_product_impl<Other,Dim,HDim, HDim,HDim>
00755 {
00756   typedef Transform<typename Other::Scalar,Dim> TransformType;
00757   typedef typename TransformType::MatrixType MatrixType;
00758   typedef typename ProductReturnType<MatrixType,Other>::Type ResultType;
00759   static ResultType run(const TransformType& tr, const Other& other)
00760   { return tr.matrix() * other; }
00761 };
00762 
00763 template<typename Other, int Dim, int HDim>
00764 struct ei_transform_product_impl<Other,Dim,HDim, Dim,Dim>
00765 {
00766   typedef Transform<typename Other::Scalar,Dim> TransformType;
00767   typedef typename TransformType::MatrixType MatrixType;
00768   typedef TransformType ResultType;
00769   static ResultType run(const TransformType& tr, const Other& other)
00770   {
00771     TransformType res;
00772     res.translation() = tr.translation();
00773     res.matrix().row(Dim) = tr.matrix().row(Dim);
00774     res.linear() = (tr.linear() * other).lazy();
00775     return res;
00776   }
00777 };
00778 
00779 template<typename Other, int Dim, int HDim>
00780 struct ei_transform_product_impl<Other,Dim,HDim, HDim,1>
00781 {
00782   typedef Transform<typename Other::Scalar,Dim> TransformType;
00783   typedef typename TransformType::MatrixType MatrixType;
00784   typedef typename ProductReturnType<MatrixType,Other>::Type ResultType;
00785   static ResultType run(const TransformType& tr, const Other& other)
00786   { return tr.matrix() * other; }
00787 };
00788 
00789 template<typename Other, int Dim, int HDim>
00790 struct ei_transform_product_impl<Other,Dim,HDim, Dim,1>
00791 {
00792   typedef typename Other::Scalar Scalar;
00793   typedef Transform<Scalar,Dim> TransformType;
00794   typedef Matrix<Scalar,Dim,1> ResultType;
00795   static ResultType run(const TransformType& tr, const Other& other)
00796   { return ((tr.linear() * other) + tr.translation())
00797           * (Scalar(1) / ( (tr.matrix().template block<1,Dim>(Dim,0) * other).coeff(0) + tr.matrix().coeff(Dim,Dim))); }
00798 };


libicr
Author(s): Robert Krug
autogenerated on Mon Jan 6 2014 11:33:44