Transform.h revision 7faaa9f3f0df9d23790277834d426c3d992ac3ba
1ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// This file is part of Eigen, a lightweight C++ template library 2ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// for linear algebra. 3ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// 4ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> 5ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com> 6ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// 7ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// This Source Code Form is subject to the terms of the Mozilla 8ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// Public License v. 2.0. If a copy of the MPL was not distributed 9ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 10ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 11ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway 12ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 13ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannnamespace Eigen { 14ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 15ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// Note that we have to pass Dim and HDim because it is not allowed to use a template 16ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// parameter to define a template specialization. To be more precise, in the following 17ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// specializations, it is not allowed to use Dim+1 instead of HDim. 18ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmanntemplate< typename Other, 19ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int Dim, 20ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int HDim, 21ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int OtherRows=Other::RowsAtCompileTime, 22ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int OtherCols=Other::ColsAtCompileTime> 23ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannstruct ei_transform_product_impl; 24ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 25ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann/** \geometry_module \ingroup Geometry_Module 26ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * 27ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * \class Transform 28ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * 29ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * \brief Represents an homogeneous transformation in a N dimensional space 30ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * 31ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * \param _Scalar the scalar type, i.e., the type of the coefficients 32ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * \param _Dim the dimension of the space 33ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * 34ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * The homography is internally represented and stored as a (Dim+1)^2 matrix which 35ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * is available through the matrix() method. 36ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * 37ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * Conversion methods from/to Qt's QMatrix and QTransform are available if the 38ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * preprocessor token EIGEN_QT_SUPPORT is defined. 39ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * 40ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * \sa class Matrix, class Quaternion 41ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann */ 42ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmanntemplate<typename _Scalar, int _Dim> 43ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannclass Transform 44ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann{ 45ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannpublic: 46ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_Dim==Dynamic ? Dynamic : (_Dim+1)*(_Dim+1)) 47ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann enum { 48ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann Dim = _Dim, ///< space dimension in which the transformation holds 49ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann HDim = _Dim+1 ///< size of a respective homogeneous vector 50ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann }; 51ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** the scalar type of the coefficients */ 52ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann typedef _Scalar Scalar; 53ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** type of the matrix used to represent the transformation */ 54ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann typedef Matrix<Scalar,HDim,HDim> MatrixType; 55ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** type of the matrix used to represent the linear part of the transformation */ 56ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann typedef Matrix<Scalar,Dim,Dim> LinearMatrixType; 57ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** type of read/write reference to the linear part of the transformation */ 58ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann typedef Block<MatrixType,Dim,Dim> LinearPart; 59ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** type of read/write reference to the linear part of the transformation */ 60ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann typedef const Block<const MatrixType,Dim,Dim> ConstLinearPart; 61ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** type of a vector */ 62ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann typedef Matrix<Scalar,Dim,1> VectorType; 63ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** type of a read/write reference to the translation part of the rotation */ 64ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann typedef Block<MatrixType,Dim,1> TranslationPart; 65ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** type of a read/write reference to the translation part of the rotation */ 66ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann typedef const Block<const MatrixType,Dim,1> ConstTranslationPart; 67ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** corresponding translation type */ 68ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann typedef Translation<Scalar,Dim> TranslationType; 69ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** corresponding scaling transformation type */ 70ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann typedef Scaling<Scalar,Dim> ScalingType; 71ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 72ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannprotected: 73ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 74ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann MatrixType m_matrix; 75ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 76ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannpublic: 77ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 78ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** Default constructor without initialization of the coefficients. */ 79ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline Transform() { } 80ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 81ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline Transform(const Transform& other) 82ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann { 83ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_matrix = other.m_matrix; 84ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 85ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 86ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline explicit Transform(const TranslationType& t) { *this = t; } 87ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline explicit Transform(const ScalingType& s) { *this = s; } 88ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann template<typename Derived> 89ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline explicit Transform(const RotationBase<Derived, Dim>& r) { *this = r; } 90ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 91ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline Transform& operator=(const Transform& other) 92ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann { m_matrix = other.m_matrix; return *this; } 93ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 94ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann template<typename OtherDerived, bool BigMatrix> // MSVC 2005 will commit suicide if BigMatrix has a default value 95ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann struct construct_from_matrix 96ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann { 97ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann static inline void run(Transform *transform, const MatrixBase<OtherDerived>& other) 98ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann { 99ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann transform->matrix() = other; 100ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 101ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann }; 102ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 103ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann template<typename OtherDerived> struct construct_from_matrix<OtherDerived, true> 104ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann { 105ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann static inline void run(Transform *transform, const MatrixBase<OtherDerived>& other) 106ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann { 107ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann transform->linear() = other; 108ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann transform->translation().setZero(); 109ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann transform->matrix()(Dim,Dim) = Scalar(1); 110ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann transform->matrix().template block<1,Dim>(Dim,0).setZero(); 111ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 112ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann }; 113ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 114ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** Constructs and initializes a transformation from a Dim^2 or a (Dim+1)^2 matrix. */ 115ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann template<typename OtherDerived> 116ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline explicit Transform(const MatrixBase<OtherDerived>& other) 117ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann { 118ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann construct_from_matrix<OtherDerived, int(OtherDerived::RowsAtCompileTime) == Dim>::run(this, other); 119ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 120ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 121ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** Set \c *this from a (Dim+1)^2 matrix. */ 122ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann template<typename OtherDerived> 123ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline Transform& operator=(const MatrixBase<OtherDerived>& other) 124ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann { m_matrix = other; return *this; } 125ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 126ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann #ifdef EIGEN_QT_SUPPORT 127ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline Transform(const QMatrix& other); 128ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline Transform& operator=(const QMatrix& other); 129ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline QMatrix toQMatrix(void) const; 130ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline Transform(const QTransform& other); 131ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline Transform& operator=(const QTransform& other); 132ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline QTransform toQTransform(void) const; 133ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann #endif 134ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 135ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** shortcut for m_matrix(row,col); 136ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * \sa MatrixBase::operaror(int,int) const */ 137ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline Scalar operator() (int row, int col) const { return m_matrix(row,col); } 138ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** shortcut for m_matrix(row,col); 139ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * \sa MatrixBase::operaror(int,int) */ 140ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline Scalar& operator() (int row, int col) { return m_matrix(row,col); } 141ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 142ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** \returns a read-only expression of the transformation matrix */ 143ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline const MatrixType& matrix() const { return m_matrix; } 144ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** \returns a writable expression of the transformation matrix */ 145ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline MatrixType& matrix() { return m_matrix; } 146ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 147ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** \returns a read-only expression of the linear (linear) part of the transformation */ 148ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline ConstLinearPart linear() const { return m_matrix.template block<Dim,Dim>(0,0); } 149ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** \returns a writable expression of the linear (linear) part of the transformation */ 150ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline LinearPart linear() { return m_matrix.template block<Dim,Dim>(0,0); } 151ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 152ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** \returns a read-only expression of the translation vector of the transformation */ 153ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline ConstTranslationPart translation() const { return m_matrix.template block<Dim,1>(0,Dim); } 154ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** \returns a writable expression of the translation vector of the transformation */ 155ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline TranslationPart translation() { return m_matrix.template block<Dim,1>(0,Dim); } 156ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 157ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** \returns an expression of the product between the transform \c *this and a matrix expression \a other 158ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * 159ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * The right hand side \a other might be either: 160ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * \li a vector of size Dim, 161ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * \li an homogeneous vector of size Dim+1, 162ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * \li a transformation matrix of size Dim+1 x Dim+1. 163ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann */ 164ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann // note: this function is defined here because some compilers cannot find the respective declaration 165ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann template<typename OtherDerived> 166ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline const typename ei_transform_product_impl<OtherDerived,_Dim,_Dim+1>::ResultType 167ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann operator * (const MatrixBase<OtherDerived> &other) const 168ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann { return ei_transform_product_impl<OtherDerived,Dim,HDim>::run(*this,other.derived()); } 169ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 170ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** \returns the product expression of a transformation matrix \a a times a transform \a b 171ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * The transformation matrix \a a must have a Dim+1 x Dim+1 sizes. */ 172ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann template<typename OtherDerived> 173ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann friend inline const typename ProductReturnType<OtherDerived,MatrixType>::Type 174ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann operator * (const MatrixBase<OtherDerived> &a, const Transform &b) 175ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann { return a.derived() * b.matrix(); } 176ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 177ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** Contatenates two transformations */ 178ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline const Transform 179ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann operator * (const Transform& other) const 180ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann { return Transform(m_matrix * other.matrix()); } 181ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 182ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** \sa MatrixBase::setIdentity() */ 183ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann void setIdentity() { m_matrix.setIdentity(); } 184ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann static const typename MatrixType::IdentityReturnType Identity() 185ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann { 186ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return MatrixType::Identity(); 187ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 188ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 189ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann template<typename OtherDerived> 190ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline Transform& scale(const MatrixBase<OtherDerived> &other); 191ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 192ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann template<typename OtherDerived> 193ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline Transform& prescale(const MatrixBase<OtherDerived> &other); 194ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 195ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline Transform& scale(Scalar s); 196ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline Transform& prescale(Scalar s); 197ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 198ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann template<typename OtherDerived> 199ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline Transform& translate(const MatrixBase<OtherDerived> &other); 200ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 201ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann template<typename OtherDerived> 202ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline Transform& pretranslate(const MatrixBase<OtherDerived> &other); 203ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 204ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann template<typename RotationType> 205ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline Transform& rotate(const RotationType& rotation); 206ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 207ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann template<typename RotationType> 208ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline Transform& prerotate(const RotationType& rotation); 209ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 210ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann Transform& shear(Scalar sx, Scalar sy); 211ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann Transform& preshear(Scalar sx, Scalar sy); 212ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 213ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline Transform& operator=(const TranslationType& t); 214ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline Transform& operator*=(const TranslationType& t) { return translate(t.vector()); } 215ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline Transform operator*(const TranslationType& t) const; 216ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 217ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline Transform& operator=(const ScalingType& t); 218ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline Transform& operator*=(const ScalingType& s) { return scale(s.coeffs()); } 219ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline Transform operator*(const ScalingType& s) const; 220ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann friend inline Transform operator*(const LinearMatrixType& mat, const Transform& t) 221ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann { 222ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann Transform res = t; 223ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann res.matrix().row(Dim) = t.matrix().row(Dim); 224ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann res.matrix().template block<Dim,HDim>(0,0) = (mat * t.matrix().template block<Dim,HDim>(0,0)).lazy(); 225ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return res; 226ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 227ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 228ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann template<typename Derived> 229ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline Transform& operator=(const RotationBase<Derived,Dim>& r); 230ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann template<typename Derived> 231ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline Transform& operator*=(const RotationBase<Derived,Dim>& r) { return rotate(r.toRotationMatrix()); } 232ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann template<typename Derived> 233ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline Transform operator*(const RotationBase<Derived,Dim>& r) const; 234ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 235ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann LinearMatrixType rotation() const; 236ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann template<typename RotationMatrixType, typename ScalingMatrixType> 237ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann void computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const; 238ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann template<typename ScalingMatrixType, typename RotationMatrixType> 239ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann void computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const; 240ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 241ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann template<typename PositionDerived, typename OrientationType, typename ScaleDerived> 242ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann Transform& fromPositionOrientationScale(const MatrixBase<PositionDerived> &position, 243ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const OrientationType& orientation, const MatrixBase<ScaleDerived> &scale); 244ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 245ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline const MatrixType inverse(TransformTraits traits = Affine) const; 246ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 247ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** \returns a const pointer to the column major internal matrix */ 248ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const Scalar* data() const { return m_matrix.data(); } 249ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** \returns a non-const pointer to the column major internal matrix */ 250ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann Scalar* data() { return m_matrix.data(); } 251ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 252ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** \returns \c *this with scalar type casted to \a NewScalarType 253ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * 254ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * Note that if \a NewScalarType is equal to the current scalar type of \c *this 255ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * then this function smartly returns a const reference to \c *this. 256ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann */ 257ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann template<typename NewScalarType> 258ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline typename internal::cast_return_type<Transform,Transform<NewScalarType,Dim> >::type cast() const 259ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann { return typename internal::cast_return_type<Transform,Transform<NewScalarType,Dim> >::type(*this); } 260ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 261ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** Copy constructor with scalar type conversion */ 262ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann template<typename OtherScalarType> 263ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inline explicit Transform(const Transform<OtherScalarType,Dim>& other) 264ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann { m_matrix = other.matrix().template cast<Scalar>(); } 265ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 266ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /** \returns \c true if \c *this is approximately equal to \a other, within the precision 267ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * determined by \a prec. 268ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * 269ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * \sa MatrixBase::isApprox() */ 270ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann bool isApprox(const Transform& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const 271ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann { return m_matrix.isApprox(other.m_matrix, prec); } 272ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 273ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann #ifdef EIGEN_TRANSFORM_PLUGIN 274ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann #include EIGEN_TRANSFORM_PLUGIN 275ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann #endif 276ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 277ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannprotected: 278ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 279ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann}; 280ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 281ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann/** \ingroup Geometry_Module */ 282ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmanntypedef Transform<float,2> Transform2f; 283ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann/** \ingroup Geometry_Module */ 284ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmanntypedef Transform<float,3> Transform3f; 285ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann/** \ingroup Geometry_Module */ 286ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmanntypedef Transform<double,2> Transform2d; 287ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann/** \ingroup Geometry_Module */ 288ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmanntypedef Transform<double,3> Transform3d; 289ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 290ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann/************************** 291ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann*** Optional QT support *** 292ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann**************************/ 293ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 294ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#ifdef EIGEN_QT_SUPPORT 295ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann/** Initialises \c *this from a QMatrix assuming the dimension is 2. 296ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * 297ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * This function is available only if the token EIGEN_QT_SUPPORT is defined. 298ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann */ 299ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmanntemplate<typename Scalar, int Dim> 300ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannTransform<Scalar,Dim>::Transform(const QMatrix& other) 301ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann{ 302ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann *this = other; 303ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 304ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 305ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann/** Set \c *this from a QMatrix assuming the dimension is 2. 306ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * 307ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * This function is available only if the token EIGEN_QT_SUPPORT is defined. 308ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann */ 309ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmanntemplate<typename Scalar, int Dim> 310ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannTransform<Scalar,Dim>& Transform<Scalar,Dim>::operator=(const QMatrix& other) 311ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann{ 312ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE) 313ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_matrix << other.m11(), other.m21(), other.dx(), 314ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann other.m12(), other.m22(), other.dy(), 315ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0, 0, 1; 316ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return *this; 317ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 318ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 319ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann/** \returns a QMatrix from \c *this assuming the dimension is 2. 320ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * 321ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * \warning this convertion might loss data if \c *this is not affine 322ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * 323ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * This function is available only if the token EIGEN_QT_SUPPORT is defined. 324ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann */ 325ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmanntemplate<typename Scalar, int Dim> 326ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannQMatrix Transform<Scalar,Dim>::toQMatrix(void) const 327ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann{ 328ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE) 329ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return QMatrix(m_matrix.coeff(0,0), m_matrix.coeff(1,0), 330ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_matrix.coeff(0,1), m_matrix.coeff(1,1), 331ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_matrix.coeff(0,2), m_matrix.coeff(1,2)); 332ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 333ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 334ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann/** Initialises \c *this from a QTransform assuming the dimension is 2. 335ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * 336ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * This function is available only if the token EIGEN_QT_SUPPORT is defined. 337ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann */ 338ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmanntemplate<typename Scalar, int Dim> 339ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannTransform<Scalar,Dim>::Transform(const QTransform& other) 340ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann{ 341ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann *this = other; 342ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 343ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 344ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann/** Set \c *this from a QTransform assuming the dimension is 2. 345ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * 346ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * This function is available only if the token EIGEN_QT_SUPPORT is defined. 347ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann */ 348ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmanntemplate<typename Scalar, int Dim> 349ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannTransform<Scalar,Dim>& Transform<Scalar,Dim>::operator=(const QTransform& other) 350ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann{ 351ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE) 352ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_matrix << other.m11(), other.m21(), other.dx(), 353ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann other.m12(), other.m22(), other.dy(), 354ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann other.m13(), other.m23(), other.m33(); 355ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return *this; 356ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 357ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 358ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann/** \returns a QTransform from \c *this assuming the dimension is 2. 359ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * 360ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * This function is available only if the token EIGEN_QT_SUPPORT is defined. 361ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann */ 362ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmanntemplate<typename Scalar, int Dim> 363ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannQTransform Transform<Scalar,Dim>::toQTransform(void) const 364ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann{ 365ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE) 366ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return QTransform(m_matrix.coeff(0,0), m_matrix.coeff(1,0), m_matrix.coeff(2,0), 367ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_matrix.coeff(0,1), m_matrix.coeff(1,1), m_matrix.coeff(2,1), 368ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_matrix.coeff(0,2), m_matrix.coeff(1,2), m_matrix.coeff(2,2)); 369ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 370ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#endif 371ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 372ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann/********************* 373ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann*** Procedural API *** 374ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann*********************/ 375ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 376ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann/** Applies on the right the non uniform scale transformation represented 377ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * by the vector \a other to \c *this and returns a reference to \c *this. 378ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * \sa prescale() 379ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann */ 380ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmanntemplate<typename Scalar, int Dim> 381ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmanntemplate<typename OtherDerived> 382ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannTransform<Scalar,Dim>& 383ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannTransform<Scalar,Dim>::scale(const MatrixBase<OtherDerived> &other) 384ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann{ 385ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) 386ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann linear() = (linear() * other.asDiagonal()).lazy(); 387ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return *this; 388ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 389ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 390ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann/** Applies on the right a uniform scale of a factor \a c to \c *this 391ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * and returns a reference to \c *this. 392ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * \sa prescale(Scalar) 393ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann */ 394ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmanntemplate<typename Scalar, int Dim> 395ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmanninline Transform<Scalar,Dim>& Transform<Scalar,Dim>::scale(Scalar s) 396ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann{ 397ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann linear() *= s; 398ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return *this; 399ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 400ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 401ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann/** Applies on the left the non uniform scale transformation represented 402ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * by the vector \a other to \c *this and returns a reference to \c *this. 403ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * \sa scale() 404ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann */ 405ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmanntemplate<typename Scalar, int Dim> 406ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmanntemplate<typename OtherDerived> 407ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannTransform<Scalar,Dim>& 408ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannTransform<Scalar,Dim>::prescale(const MatrixBase<OtherDerived> &other) 409ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann{ 410ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) 411ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_matrix.template block<Dim,HDim>(0,0) = (other.asDiagonal() * m_matrix.template block<Dim,HDim>(0,0)).lazy(); 412ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return *this; 413ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 414ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 415ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann/** Applies on the left a uniform scale of a factor \a c to \c *this 416ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * and returns a reference to \c *this. 417ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * \sa scale(Scalar) 418ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann */ 419ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmanntemplate<typename Scalar, int Dim> 420ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmanninline Transform<Scalar,Dim>& Transform<Scalar,Dim>::prescale(Scalar s) 421ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann{ 422ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_matrix.template corner<Dim,HDim>(TopLeft) *= s; 423ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return *this; 424ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 425ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 426ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann/** Applies on the right the translation matrix represented by the vector \a other 427ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * to \c *this and returns a reference to \c *this. 428ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * \sa pretranslate() 429ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann */ 430ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmanntemplate<typename Scalar, int Dim> 431ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmanntemplate<typename OtherDerived> 432ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannTransform<Scalar,Dim>& 433ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannTransform<Scalar,Dim>::translate(const MatrixBase<OtherDerived> &other) 434ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann{ 435ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) 436ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann translation() += linear() * other; 437ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return *this; 438ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 439ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 440ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann/** Applies on the left the translation matrix represented by the vector \a other 441ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * to \c *this and returns a reference to \c *this. 442ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * \sa translate() 443ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann */ 444ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmanntemplate<typename Scalar, int Dim> 445ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmanntemplate<typename OtherDerived> 446ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannTransform<Scalar,Dim>& 447ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannTransform<Scalar,Dim>::pretranslate(const MatrixBase<OtherDerived> &other) 448ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann{ 449ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) 450 translation() += other; 451 return *this; 452} 453 454/** Applies on the right the rotation represented by the rotation \a rotation 455 * to \c *this and returns a reference to \c *this. 456 * 457 * The template parameter \a RotationType is the type of the rotation which 458 * must be known by ei_toRotationMatrix<>. 459 * 460 * Natively supported types includes: 461 * - any scalar (2D), 462 * - a Dim x Dim matrix expression, 463 * - a Quaternion (3D), 464 * - a AngleAxis (3D) 465 * 466 * This mechanism is easily extendable to support user types such as Euler angles, 467 * or a pair of Quaternion for 4D rotations. 468 * 469 * \sa rotate(Scalar), class Quaternion, class AngleAxis, prerotate(RotationType) 470 */ 471template<typename Scalar, int Dim> 472template<typename RotationType> 473Transform<Scalar,Dim>& 474Transform<Scalar,Dim>::rotate(const RotationType& rotation) 475{ 476 linear() *= ei_toRotationMatrix<Scalar,Dim>(rotation); 477 return *this; 478} 479 480/** Applies on the left the rotation represented by the rotation \a rotation 481 * to \c *this and returns a reference to \c *this. 482 * 483 * See rotate() for further details. 484 * 485 * \sa rotate() 486 */ 487template<typename Scalar, int Dim> 488template<typename RotationType> 489Transform<Scalar,Dim>& 490Transform<Scalar,Dim>::prerotate(const RotationType& rotation) 491{ 492 m_matrix.template block<Dim,HDim>(0,0) = ei_toRotationMatrix<Scalar,Dim>(rotation) 493 * m_matrix.template block<Dim,HDim>(0,0); 494 return *this; 495} 496 497/** Applies on the right the shear transformation represented 498 * by the vector \a other to \c *this and returns a reference to \c *this. 499 * \warning 2D only. 500 * \sa preshear() 501 */ 502template<typename Scalar, int Dim> 503Transform<Scalar,Dim>& 504Transform<Scalar,Dim>::shear(Scalar sx, Scalar sy) 505{ 506 EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE) 507 VectorType tmp = linear().col(0)*sy + linear().col(1); 508 linear() << linear().col(0) + linear().col(1)*sx, tmp; 509 return *this; 510} 511 512/** Applies on the left the shear transformation represented 513 * by the vector \a other to \c *this and returns a reference to \c *this. 514 * \warning 2D only. 515 * \sa shear() 516 */ 517template<typename Scalar, int Dim> 518Transform<Scalar,Dim>& 519Transform<Scalar,Dim>::preshear(Scalar sx, Scalar sy) 520{ 521 EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE) 522 m_matrix.template block<Dim,HDim>(0,0) = LinearMatrixType(1, sx, sy, 1) * m_matrix.template block<Dim,HDim>(0,0); 523 return *this; 524} 525 526/****************************************************** 527*** Scaling, Translation and Rotation compatibility *** 528******************************************************/ 529 530template<typename Scalar, int Dim> 531inline Transform<Scalar,Dim>& Transform<Scalar,Dim>::operator=(const TranslationType& t) 532{ 533 linear().setIdentity(); 534 translation() = t.vector(); 535 m_matrix.template block<1,Dim>(Dim,0).setZero(); 536 m_matrix(Dim,Dim) = Scalar(1); 537 return *this; 538} 539 540template<typename Scalar, int Dim> 541inline Transform<Scalar,Dim> Transform<Scalar,Dim>::operator*(const TranslationType& t) const 542{ 543 Transform res = *this; 544 res.translate(t.vector()); 545 return res; 546} 547 548template<typename Scalar, int Dim> 549inline Transform<Scalar,Dim>& Transform<Scalar,Dim>::operator=(const ScalingType& s) 550{ 551 m_matrix.setZero(); 552 linear().diagonal() = s.coeffs(); 553 m_matrix.coeffRef(Dim,Dim) = Scalar(1); 554 return *this; 555} 556 557template<typename Scalar, int Dim> 558inline Transform<Scalar,Dim> Transform<Scalar,Dim>::operator*(const ScalingType& s) const 559{ 560 Transform res = *this; 561 res.scale(s.coeffs()); 562 return res; 563} 564 565template<typename Scalar, int Dim> 566template<typename Derived> 567inline Transform<Scalar,Dim>& Transform<Scalar,Dim>::operator=(const RotationBase<Derived,Dim>& r) 568{ 569 linear() = ei_toRotationMatrix<Scalar,Dim>(r); 570 translation().setZero(); 571 m_matrix.template block<1,Dim>(Dim,0).setZero(); 572 m_matrix.coeffRef(Dim,Dim) = Scalar(1); 573 return *this; 574} 575 576template<typename Scalar, int Dim> 577template<typename Derived> 578inline Transform<Scalar,Dim> Transform<Scalar,Dim>::operator*(const RotationBase<Derived,Dim>& r) const 579{ 580 Transform res = *this; 581 res.rotate(r.derived()); 582 return res; 583} 584 585/************************ 586*** Special functions *** 587************************/ 588 589/** \returns the rotation part of the transformation 590 * \nonstableyet 591 * 592 * \svd_module 593 * 594 * \sa computeRotationScaling(), computeScalingRotation(), class SVD 595 */ 596template<typename Scalar, int Dim> 597typename Transform<Scalar,Dim>::LinearMatrixType 598Transform<Scalar,Dim>::rotation() const 599{ 600 LinearMatrixType result; 601 computeRotationScaling(&result, (LinearMatrixType*)0); 602 return result; 603} 604 605 606/** decomposes the linear part of the transformation as a product rotation x scaling, the scaling being 607 * not necessarily positive. 608 * 609 * If either pointer is zero, the corresponding computation is skipped. 610 * 611 * \nonstableyet 612 * 613 * \svd_module 614 * 615 * \sa computeScalingRotation(), rotation(), class SVD 616 */ 617template<typename Scalar, int Dim> 618template<typename RotationMatrixType, typename ScalingMatrixType> 619void Transform<Scalar,Dim>::computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const 620{ 621 JacobiSVD<LinearMatrixType> svd(linear(), ComputeFullU|ComputeFullV); 622 Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant(); // so x has absolute value 1 623 Matrix<Scalar, Dim, 1> sv(svd.singularValues()); 624 sv.coeffRef(0) *= x; 625 if(scaling) 626 { 627 scaling->noalias() = svd.matrixV() * sv.asDiagonal() * svd.matrixV().adjoint(); 628 } 629 if(rotation) 630 { 631 LinearMatrixType m(svd.matrixU()); 632 m.col(0) /= x; 633 rotation->noalias() = m * svd.matrixV().adjoint(); 634 } 635} 636 637/** decomposes the linear part of the transformation as a product rotation x scaling, the scaling being 638 * not necessarily positive. 639 * 640 * If either pointer is zero, the corresponding computation is skipped. 641 * 642 * \nonstableyet 643 * 644 * \svd_module 645 * 646 * \sa computeRotationScaling(), rotation(), class SVD 647 */ 648template<typename Scalar, int Dim> 649template<typename ScalingMatrixType, typename RotationMatrixType> 650void Transform<Scalar,Dim>::computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const 651{ 652 JacobiSVD<LinearMatrixType> svd(linear(), ComputeFullU|ComputeFullV); 653 Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant(); // so x has absolute value 1 654 Matrix<Scalar, Dim, 1> sv(svd.singularValues()); 655 sv.coeffRef(0) *= x; 656 if(scaling) 657 { 658 scaling->noalias() = svd.matrixU() * sv.asDiagonal() * svd.matrixU().adjoint(); 659 } 660 if(rotation) 661 { 662 LinearMatrixType m(svd.matrixU()); 663 m.col(0) /= x; 664 rotation->noalias() = m * svd.matrixV().adjoint(); 665 } 666} 667 668/** Convenient method to set \c *this from a position, orientation and scale 669 * of a 3D object. 670 */ 671template<typename Scalar, int Dim> 672template<typename PositionDerived, typename OrientationType, typename ScaleDerived> 673Transform<Scalar,Dim>& 674Transform<Scalar,Dim>::fromPositionOrientationScale(const MatrixBase<PositionDerived> &position, 675 const OrientationType& orientation, const MatrixBase<ScaleDerived> &scale) 676{ 677 linear() = ei_toRotationMatrix<Scalar,Dim>(orientation); 678 linear() *= scale.asDiagonal(); 679 translation() = position; 680 m_matrix.template block<1,Dim>(Dim,0).setZero(); 681 m_matrix(Dim,Dim) = Scalar(1); 682 return *this; 683} 684 685/** \nonstableyet 686 * 687 * \returns the inverse transformation matrix according to some given knowledge 688 * on \c *this. 689 * 690 * \param traits allows to optimize the inversion process when the transformion 691 * is known to be not a general transformation. The possible values are: 692 * - Projective if the transformation is not necessarily affine, i.e., if the 693 * last row is not guaranteed to be [0 ... 0 1] 694 * - Affine is the default, the last row is assumed to be [0 ... 0 1] 695 * - Isometry if the transformation is only a concatenations of translations 696 * and rotations. 697 * 698 * \warning unless \a traits is always set to NoShear or NoScaling, this function 699 * requires the generic inverse method of MatrixBase defined in the LU module. If 700 * you forget to include this module, then you will get hard to debug linking errors. 701 * 702 * \sa MatrixBase::inverse() 703 */ 704template<typename Scalar, int Dim> 705inline const typename Transform<Scalar,Dim>::MatrixType 706Transform<Scalar,Dim>::inverse(TransformTraits traits) const 707{ 708 if (traits == Projective) 709 { 710 return m_matrix.inverse(); 711 } 712 else 713 { 714 MatrixType res; 715 if (traits == Affine) 716 { 717 res.template corner<Dim,Dim>(TopLeft) = linear().inverse(); 718 } 719 else if (traits == Isometry) 720 { 721 res.template corner<Dim,Dim>(TopLeft) = linear().transpose(); 722 } 723 else 724 { 725 ei_assert("invalid traits value in Transform::inverse()"); 726 } 727 // translation and remaining parts 728 res.template corner<Dim,1>(TopRight) = - res.template corner<Dim,Dim>(TopLeft) * translation(); 729 res.template corner<1,Dim>(BottomLeft).setZero(); 730 res.coeffRef(Dim,Dim) = Scalar(1); 731 return res; 732 } 733} 734 735/***************************************************** 736*** Specializations of operator* with a MatrixBase *** 737*****************************************************/ 738 739template<typename Other, int Dim, int HDim> 740struct ei_transform_product_impl<Other,Dim,HDim, HDim,HDim> 741{ 742 typedef Transform<typename Other::Scalar,Dim> TransformType; 743 typedef typename TransformType::MatrixType MatrixType; 744 typedef typename ProductReturnType<MatrixType,Other>::Type ResultType; 745 static ResultType run(const TransformType& tr, const Other& other) 746 { return tr.matrix() * other; } 747}; 748 749template<typename Other, int Dim, int HDim> 750struct ei_transform_product_impl<Other,Dim,HDim, Dim,Dim> 751{ 752 typedef Transform<typename Other::Scalar,Dim> TransformType; 753 typedef typename TransformType::MatrixType MatrixType; 754 typedef TransformType ResultType; 755 static ResultType run(const TransformType& tr, const Other& other) 756 { 757 TransformType res; 758 res.translation() = tr.translation(); 759 res.matrix().row(Dim) = tr.matrix().row(Dim); 760 res.linear() = (tr.linear() * other).lazy(); 761 return res; 762 } 763}; 764 765template<typename Other, int Dim, int HDim> 766struct ei_transform_product_impl<Other,Dim,HDim, HDim,1> 767{ 768 typedef Transform<typename Other::Scalar,Dim> TransformType; 769 typedef typename TransformType::MatrixType MatrixType; 770 typedef typename ProductReturnType<MatrixType,Other>::Type ResultType; 771 static ResultType run(const TransformType& tr, const Other& other) 772 { return tr.matrix() * other; } 773}; 774 775template<typename Other, int Dim, int HDim> 776struct ei_transform_product_impl<Other,Dim,HDim, Dim,1> 777{ 778 typedef typename Other::Scalar Scalar; 779 typedef Transform<Scalar,Dim> TransformType; 780 typedef Matrix<Scalar,Dim,1> ResultType; 781 static ResultType run(const TransformType& tr, const Other& other) 782 { return ((tr.linear() * other) + tr.translation()) 783 * (Scalar(1) / ( (tr.matrix().template block<1,Dim>(Dim,0) * other).coeff(0) + tr.matrix().coeff(Dim,Dim))); } 784}; 785 786} // end namespace Eigen 787