Home | History | Annotate | Download | only in Geometry
      1 // This file is part of Eigen, a lightweight C++ template library
      2 // for linear algebra.
      3 //
      4 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud (at) inria.fr>
      5 // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1 (at) gmail.com>
      6 // Copyright (C) 2010 Hauke Heibel <hauke.heibel (at) gmail.com>
      7 //
      8 // This Source Code Form is subject to the terms of the Mozilla
      9 // Public License v. 2.0. If a copy of the MPL was not distributed
     10 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
     11 
     12 #ifndef EIGEN_TRANSFORM_H
     13 #define EIGEN_TRANSFORM_H
     14 
     15 namespace Eigen {
     16 
     17 namespace internal {
     18 
     19 template<typename Transform>
     20 struct transform_traits
     21 {
     22   enum
     23   {
     24     Dim = Transform::Dim,
     25     HDim = Transform::HDim,
     26     Mode = Transform::Mode,
     27     IsProjective = (int(Mode)==int(Projective))
     28   };
     29 };
     30 
     31 template< typename TransformType,
     32           typename MatrixType,
     33           int Case = transform_traits<TransformType>::IsProjective ? 0
     34                    : int(MatrixType::RowsAtCompileTime) == int(transform_traits<TransformType>::HDim) ? 1
     35                    : 2>
     36 struct transform_right_product_impl;
     37 
     38 template< typename Other,
     39           int Mode,
     40           int Options,
     41           int Dim,
     42           int HDim,
     43           int OtherRows=Other::RowsAtCompileTime,
     44           int OtherCols=Other::ColsAtCompileTime>
     45 struct transform_left_product_impl;
     46 
     47 template< typename Lhs,
     48           typename Rhs,
     49           bool AnyProjective =
     50             transform_traits<Lhs>::IsProjective ||
     51             transform_traits<Rhs>::IsProjective>
     52 struct transform_transform_product_impl;
     53 
     54 template< typename Other,
     55           int Mode,
     56           int Options,
     57           int Dim,
     58           int HDim,
     59           int OtherRows=Other::RowsAtCompileTime,
     60           int OtherCols=Other::ColsAtCompileTime>
     61 struct transform_construct_from_matrix;
     62 
     63 template<typename TransformType> struct transform_take_affine_part;
     64 
     65 template<int Mode> struct transform_make_affine;
     66 
     67 } // end namespace internal
     68 
     69 /** \geometry_module \ingroup Geometry_Module
     70   *
     71   * \class Transform
     72   *
     73   * \brief Represents an homogeneous transformation in a N dimensional space
     74   *
     75   * \tparam _Scalar the scalar type, i.e., the type of the coefficients
     76   * \tparam _Dim the dimension of the space
     77   * \tparam _Mode the type of the transformation. Can be:
     78   *              - #Affine: the transformation is stored as a (Dim+1)^2 matrix,
     79   *                         where the last row is assumed to be [0 ... 0 1].
     80   *              - #AffineCompact: the transformation is stored as a (Dim)x(Dim+1) matrix.
     81   *              - #Projective: the transformation is stored as a (Dim+1)^2 matrix
     82   *                             without any assumption.
     83   * \tparam _Options has the same meaning as in class Matrix. It allows to specify DontAlign and/or RowMajor.
     84   *                  These Options are passed directly to the underlying matrix type.
     85   *
     86   * The homography is internally represented and stored by a matrix which
     87   * is available through the matrix() method. To understand the behavior of
     88   * this class you have to think a Transform object as its internal
     89   * matrix representation. The chosen convention is right multiply:
     90   *
     91   * \code v' = T * v \endcode
     92   *
     93   * Therefore, an affine transformation matrix M is shaped like this:
     94   *
     95   * \f$ \left( \begin{array}{cc}
     96   * linear & translation\\
     97   * 0 ... 0 & 1
     98   * \end{array} \right) \f$
     99   *
    100   * Note that for a projective transformation the last row can be anything,
    101   * and then the interpretation of different parts might be sightly different.
    102   *
    103   * However, unlike a plain matrix, the Transform class provides many features
    104   * simplifying both its assembly and usage. In particular, it can be composed
    105   * with any other transformations (Transform,Translation,RotationBase,Matrix)
    106   * and can be directly used to transform implicit homogeneous vectors. All these
    107   * operations are handled via the operator*. For the composition of transformations,
    108   * its principle consists to first convert the right/left hand sides of the product
    109   * to a compatible (Dim+1)^2 matrix and then perform a pure matrix product.
    110   * Of course, internally, operator* tries to perform the minimal number of operations
    111   * according to the nature of each terms. Likewise, when applying the transform
    112   * to non homogeneous vectors, the latters are automatically promoted to homogeneous
    113   * one before doing the matrix product. The convertions to homogeneous representations
    114   * are performed as follow:
    115   *
    116   * \b Translation t (Dim)x(1):
    117   * \f$ \left( \begin{array}{cc}
    118   * I & t \\
    119   * 0\,...\,0 & 1
    120   * \end{array} \right) \f$
    121   *
    122   * \b Rotation R (Dim)x(Dim):
    123   * \f$ \left( \begin{array}{cc}
    124   * R & 0\\
    125   * 0\,...\,0 & 1
    126   * \end{array} \right) \f$
    127   *
    128   * \b Linear \b Matrix L (Dim)x(Dim):
    129   * \f$ \left( \begin{array}{cc}
    130   * L & 0\\
    131   * 0\,...\,0 & 1
    132   * \end{array} \right) \f$
    133   *
    134   * \b Affine \b Matrix A (Dim)x(Dim+1):
    135   * \f$ \left( \begin{array}{c}
    136   * A\\
    137   * 0\,...\,0\,1
    138   * \end{array} \right) \f$
    139   *
    140   * \b Column \b vector v (Dim)x(1):
    141   * \f$ \left( \begin{array}{c}
    142   * v\\
    143   * 1
    144   * \end{array} \right) \f$
    145   *
    146   * \b Set \b of \b column \b vectors V1...Vn (Dim)x(n):
    147   * \f$ \left( \begin{array}{ccc}
    148   * v_1 & ... & v_n\\
    149   * 1 & ... & 1
    150   * \end{array} \right) \f$
    151   *
    152   * The concatenation of a Transform object with any kind of other transformation
    153   * always returns a Transform object.
    154   *
    155   * A little exception to the "as pure matrix product" rule is the case of the
    156   * transformation of non homogeneous vectors by an affine transformation. In
    157   * that case the last matrix row can be ignored, and the product returns non
    158   * homogeneous vectors.
    159   *
    160   * Since, for instance, a Dim x Dim matrix is interpreted as a linear transformation,
    161   * it is not possible to directly transform Dim vectors stored in a Dim x Dim matrix.
    162   * The solution is either to use a Dim x Dynamic matrix or explicitly request a
    163   * vector transformation by making the vector homogeneous:
    164   * \code
    165   * m' = T * m.colwise().homogeneous();
    166   * \endcode
    167   * Note that there is zero overhead.
    168   *
    169   * Conversion methods from/to Qt's QMatrix and QTransform are available if the
    170   * preprocessor token EIGEN_QT_SUPPORT is defined.
    171   *
    172   * This class can be extended with the help of the plugin mechanism described on the page
    173   * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_TRANSFORM_PLUGIN.
    174   *
    175   * \sa class Matrix, class Quaternion
    176   */
    177 template<typename _Scalar, int _Dim, int _Mode, int _Options>
    178 class Transform
    179 {
    180 public:
    181   EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_Dim==Dynamic ? Dynamic : (_Dim+1)*(_Dim+1))
    182   enum {
    183     Mode = _Mode,
    184     Options = _Options,
    185     Dim = _Dim,     ///< space dimension in which the transformation holds
    186     HDim = _Dim+1,  ///< size of a respective homogeneous vector
    187     Rows = int(Mode)==(AffineCompact) ? Dim : HDim
    188   };
    189   /** the scalar type of the coefficients */
    190   typedef _Scalar Scalar;
    191   typedef DenseIndex Index;
    192   /** type of the matrix used to represent the transformation */
    193   typedef typename internal::make_proper_matrix_type<Scalar,Rows,HDim,Options>::type MatrixType;
    194   /** constified MatrixType */
    195   typedef const MatrixType ConstMatrixType;
    196   /** type of the matrix used to represent the linear part of the transformation */
    197   typedef Matrix<Scalar,Dim,Dim,Options> LinearMatrixType;
    198   /** type of read/write reference to the linear part of the transformation */
    199   typedef Block<MatrixType,Dim,Dim,int(Mode)==(AffineCompact) && (Options&RowMajor)==0> LinearPart;
    200   /** type of read reference to the linear part of the transformation */
    201   typedef const Block<ConstMatrixType,Dim,Dim,int(Mode)==(AffineCompact) && (Options&RowMajor)==0> ConstLinearPart;
    202   /** type of read/write reference to the affine part of the transformation */
    203   typedef typename internal::conditional<int(Mode)==int(AffineCompact),
    204                               MatrixType&,
    205                               Block<MatrixType,Dim,HDim> >::type AffinePart;
    206   /** type of read reference to the affine part of the transformation */
    207   typedef typename internal::conditional<int(Mode)==int(AffineCompact),
    208                               const MatrixType&,
    209                               const Block<const MatrixType,Dim,HDim> >::type ConstAffinePart;
    210   /** type of a vector */
    211   typedef Matrix<Scalar,Dim,1> VectorType;
    212   /** type of a read/write reference to the translation part of the rotation */
    213   typedef Block<MatrixType,Dim,1,int(Mode)==(AffineCompact)> TranslationPart;
    214   /** type of a read reference to the translation part of the rotation */
    215   typedef const Block<ConstMatrixType,Dim,1,int(Mode)==(AffineCompact)> ConstTranslationPart;
    216   /** corresponding translation type */
    217   typedef Translation<Scalar,Dim> TranslationType;
    218 
    219   // this intermediate enum is needed to avoid an ICE with gcc 3.4 and 4.0
    220   enum { TransformTimeDiagonalMode = ((Mode==int(Isometry))?Affine:int(Mode)) };
    221   /** The return type of the product between a diagonal matrix and a transform */
    222   typedef Transform<Scalar,Dim,TransformTimeDiagonalMode> TransformTimeDiagonalReturnType;
    223 
    224 protected:
    225 
    226   MatrixType m_matrix;
    227 
    228 public:
    229 
    230   /** Default constructor without initialization of the meaningful coefficients.
    231     * If Mode==Affine, then the last row is set to [0 ... 0 1] */
    232   inline Transform()
    233   {
    234     check_template_params();
    235     internal::transform_make_affine<(int(Mode)==Affine) ? Affine : AffineCompact>::run(m_matrix);
    236   }
    237 
    238   inline Transform(const Transform& other)
    239   {
    240     check_template_params();
    241     m_matrix = other.m_matrix;
    242   }
    243 
    244   inline explicit Transform(const TranslationType& t)
    245   {
    246     check_template_params();
    247     *this = t;
    248   }
    249   inline explicit Transform(const UniformScaling<Scalar>& s)
    250   {
    251     check_template_params();
    252     *this = s;
    253   }
    254   template<typename Derived>
    255   inline explicit Transform(const RotationBase<Derived, Dim>& r)
    256   {
    257     check_template_params();
    258     *this = r;
    259   }
    260 
    261   inline Transform& operator=(const Transform& other)
    262   { m_matrix = other.m_matrix; return *this; }
    263 
    264   typedef internal::transform_take_affine_part<Transform> take_affine_part;
    265 
    266   /** Constructs and initializes a transformation from a Dim^2 or a (Dim+1)^2 matrix. */
    267   template<typename OtherDerived>
    268   inline explicit Transform(const EigenBase<OtherDerived>& other)
    269   {
    270     EIGEN_STATIC_ASSERT((internal::is_same<Scalar,typename OtherDerived::Scalar>::value),
    271       YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY);
    272 
    273     check_template_params();
    274     internal::transform_construct_from_matrix<OtherDerived,Mode,Options,Dim,HDim>::run(this, other.derived());
    275   }
    276 
    277   /** Set \c *this from a Dim^2 or (Dim+1)^2 matrix. */
    278   template<typename OtherDerived>
    279   inline Transform& operator=(const EigenBase<OtherDerived>& other)
    280   {
    281     EIGEN_STATIC_ASSERT((internal::is_same<Scalar,typename OtherDerived::Scalar>::value),
    282       YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY);
    283 
    284     internal::transform_construct_from_matrix<OtherDerived,Mode,Options,Dim,HDim>::run(this, other.derived());
    285     return *this;
    286   }
    287 
    288   template<int OtherOptions>
    289   inline Transform(const Transform<Scalar,Dim,Mode,OtherOptions>& other)
    290   {
    291     check_template_params();
    292     // only the options change, we can directly copy the matrices
    293     m_matrix = other.matrix();
    294   }
    295 
    296   template<int OtherMode,int OtherOptions>
    297   inline Transform(const Transform<Scalar,Dim,OtherMode,OtherOptions>& other)
    298   {
    299     check_template_params();
    300     // prevent conversions as:
    301     // Affine | AffineCompact | Isometry = Projective
    302     EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(OtherMode==int(Projective), Mode==int(Projective)),
    303                         YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION)
    304 
    305     // prevent conversions as:
    306     // Isometry = Affine | AffineCompact
    307     EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(OtherMode==int(Affine)||OtherMode==int(AffineCompact), Mode!=int(Isometry)),
    308                         YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION)
    309 
    310     enum { ModeIsAffineCompact = Mode == int(AffineCompact),
    311            OtherModeIsAffineCompact = OtherMode == int(AffineCompact)
    312     };
    313 
    314     if(ModeIsAffineCompact == OtherModeIsAffineCompact)
    315     {
    316       // We need the block expression because the code is compiled for all
    317       // combinations of transformations and will trigger a compile time error
    318       // if one tries to assign the matrices directly
    319       m_matrix.template block<Dim,Dim+1>(0,0) = other.matrix().template block<Dim,Dim+1>(0,0);
    320       makeAffine();
    321     }
    322     else if(OtherModeIsAffineCompact)
    323     {
    324       typedef typename Transform<Scalar,Dim,OtherMode,OtherOptions>::MatrixType OtherMatrixType;
    325       internal::transform_construct_from_matrix<OtherMatrixType,Mode,Options,Dim,HDim>::run(this, other.matrix());
    326     }
    327     else
    328     {
    329       // here we know that Mode == AffineCompact and OtherMode != AffineCompact.
    330       // if OtherMode were Projective, the static assert above would already have caught it.
    331       // So the only possibility is that OtherMode == Affine
    332       linear() = other.linear();
    333       translation() = other.translation();
    334     }
    335   }
    336 
    337   template<typename OtherDerived>
    338   Transform(const ReturnByValue<OtherDerived>& other)
    339   {
    340     check_template_params();
    341     other.evalTo(*this);
    342   }
    343 
    344   template<typename OtherDerived>
    345   Transform& operator=(const ReturnByValue<OtherDerived>& other)
    346   {
    347     other.evalTo(*this);
    348     return *this;
    349   }
    350 
    351   #ifdef EIGEN_QT_SUPPORT
    352   inline Transform(const QMatrix& other);
    353   inline Transform& operator=(const QMatrix& other);
    354   inline QMatrix toQMatrix(void) const;
    355   inline Transform(const QTransform& other);
    356   inline Transform& operator=(const QTransform& other);
    357   inline QTransform toQTransform(void) const;
    358   #endif
    359 
    360   /** shortcut for m_matrix(row,col);
    361     * \sa MatrixBase::operator(Index,Index) const */
    362   inline Scalar operator() (Index row, Index col) const { return m_matrix(row,col); }
    363   /** shortcut for m_matrix(row,col);
    364     * \sa MatrixBase::operator(Index,Index) */
    365   inline Scalar& operator() (Index row, Index col) { return m_matrix(row,col); }
    366 
    367   /** \returns a read-only expression of the transformation matrix */
    368   inline const MatrixType& matrix() const { return m_matrix; }
    369   /** \returns a writable expression of the transformation matrix */
    370   inline MatrixType& matrix() { return m_matrix; }
    371 
    372   /** \returns a read-only expression of the linear part of the transformation */
    373   inline ConstLinearPart linear() const { return ConstLinearPart(m_matrix,0,0); }
    374   /** \returns a writable expression of the linear part of the transformation */
    375   inline LinearPart linear() { return LinearPart(m_matrix,0,0); }
    376 
    377   /** \returns a read-only expression of the Dim x HDim affine part of the transformation */
    378   inline ConstAffinePart affine() const { return take_affine_part::run(m_matrix); }
    379   /** \returns a writable expression of the Dim x HDim affine part of the transformation */
    380   inline AffinePart affine() { return take_affine_part::run(m_matrix); }
    381 
    382   /** \returns a read-only expression of the translation vector of the transformation */
    383   inline ConstTranslationPart translation() const { return ConstTranslationPart(m_matrix,0,Dim); }
    384   /** \returns a writable expression of the translation vector of the transformation */
    385   inline TranslationPart translation() { return TranslationPart(m_matrix,0,Dim); }
    386 
    387   /** \returns an expression of the product between the transform \c *this and a matrix expression \a other
    388     *
    389     * The right hand side \a other might be either:
    390     * \li a vector of size Dim,
    391     * \li an homogeneous vector of size Dim+1,
    392     * \li a set of vectors of size Dim x Dynamic,
    393     * \li a set of homogeneous vectors of size Dim+1 x Dynamic,
    394     * \li a linear transformation matrix of size Dim x Dim,
    395     * \li an affine transformation matrix of size Dim x Dim+1,
    396     * \li a transformation matrix of size Dim+1 x Dim+1.
    397     */
    398   // note: this function is defined here because some compilers cannot find the respective declaration
    399   template<typename OtherDerived>
    400   EIGEN_STRONG_INLINE const typename internal::transform_right_product_impl<Transform, OtherDerived>::ResultType
    401   operator * (const EigenBase<OtherDerived> &other) const
    402   { return internal::transform_right_product_impl<Transform, OtherDerived>::run(*this,other.derived()); }
    403 
    404   /** \returns the product expression of a transformation matrix \a a times a transform \a b
    405     *
    406     * The left hand side \a other might be either:
    407     * \li a linear transformation matrix of size Dim x Dim,
    408     * \li an affine transformation matrix of size Dim x Dim+1,
    409     * \li a general transformation matrix of size Dim+1 x Dim+1.
    410     */
    411   template<typename OtherDerived> friend
    412   inline const typename internal::transform_left_product_impl<OtherDerived,Mode,Options,_Dim,_Dim+1>::ResultType
    413     operator * (const EigenBase<OtherDerived> &a, const Transform &b)
    414   { return internal::transform_left_product_impl<OtherDerived,Mode,Options,Dim,HDim>::run(a.derived(),b); }
    415 
    416   /** \returns The product expression of a transform \a a times a diagonal matrix \a b
    417     *
    418     * The rhs diagonal matrix is interpreted as an affine scaling transformation. The
    419     * product results in a Transform of the same type (mode) as the lhs only if the lhs
    420     * mode is no isometry. In that case, the returned transform is an affinity.
    421     */
    422   template<typename DiagonalDerived>
    423   inline const TransformTimeDiagonalReturnType
    424     operator * (const DiagonalBase<DiagonalDerived> &b) const
    425   {
    426     TransformTimeDiagonalReturnType res(*this);
    427     res.linear() *= b;
    428     return res;
    429   }
    430 
    431   /** \returns The product expression of a diagonal matrix \a a times a transform \a b
    432     *
    433     * The lhs diagonal matrix is interpreted as an affine scaling transformation. The
    434     * product results in a Transform of the same type (mode) as the lhs only if the lhs
    435     * mode is no isometry. In that case, the returned transform is an affinity.
    436     */
    437   template<typename DiagonalDerived>
    438   friend inline TransformTimeDiagonalReturnType
    439     operator * (const DiagonalBase<DiagonalDerived> &a, const Transform &b)
    440   {
    441     TransformTimeDiagonalReturnType res;
    442     res.linear().noalias() = a*b.linear();
    443     res.translation().noalias() = a*b.translation();
    444     if (Mode!=int(AffineCompact))
    445       res.matrix().row(Dim) = b.matrix().row(Dim);
    446     return res;
    447   }
    448 
    449   template<typename OtherDerived>
    450   inline Transform& operator*=(const EigenBase<OtherDerived>& other) { return *this = *this * other; }
    451 
    452   /** Concatenates two transformations */
    453   inline const Transform operator * (const Transform& other) const
    454   {
    455     return internal::transform_transform_product_impl<Transform,Transform>::run(*this,other);
    456   }
    457 
    458   #ifdef __INTEL_COMPILER
    459 private:
    460   // this intermediate structure permits to workaround a bug in ICC 11:
    461   //   error: template instantiation resulted in unexpected function type of "Eigen::Transform<double, 3, 32, 0>
    462   //             (const Eigen::Transform<double, 3, 2, 0> &) const"
    463   //  (the meaning of a name may have changed since the template declaration -- the type of the template is:
    464   // "Eigen::internal::transform_transform_product_impl<Eigen::Transform<double, 3, 32, 0>,
    465   //     Eigen::Transform<double, 3, Mode, Options>, <expression>>::ResultType (const Eigen::Transform<double, 3, Mode, Options> &) const")
    466   //
    467   template<int OtherMode,int OtherOptions> struct icc_11_workaround
    468   {
    469     typedef internal::transform_transform_product_impl<Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> > ProductType;
    470     typedef typename ProductType::ResultType ResultType;
    471   };
    472 
    473 public:
    474   /** Concatenates two different transformations */
    475   template<int OtherMode,int OtherOptions>
    476   inline typename icc_11_workaround<OtherMode,OtherOptions>::ResultType
    477     operator * (const Transform<Scalar,Dim,OtherMode,OtherOptions>& other) const
    478   {
    479     typedef typename icc_11_workaround<OtherMode,OtherOptions>::ProductType ProductType;
    480     return ProductType::run(*this,other);
    481   }
    482   #else
    483   /** Concatenates two different transformations */
    484   template<int OtherMode,int OtherOptions>
    485   inline typename internal::transform_transform_product_impl<Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> >::ResultType
    486     operator * (const Transform<Scalar,Dim,OtherMode,OtherOptions>& other) const
    487   {
    488     return internal::transform_transform_product_impl<Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> >::run(*this,other);
    489   }
    490   #endif
    491 
    492   /** \sa MatrixBase::setIdentity() */
    493   void setIdentity() { m_matrix.setIdentity(); }
    494 
    495   /**
    496    * \brief Returns an identity transformation.
    497    * \todo In the future this function should be returning a Transform expression.
    498    */
    499   static const Transform Identity()
    500   {
    501     return Transform(MatrixType::Identity());
    502   }
    503 
    504   template<typename OtherDerived>
    505   inline Transform& scale(const MatrixBase<OtherDerived> &other);
    506 
    507   template<typename OtherDerived>
    508   inline Transform& prescale(const MatrixBase<OtherDerived> &other);
    509 
    510   inline Transform& scale(const Scalar& s);
    511   inline Transform& prescale(const Scalar& s);
    512 
    513   template<typename OtherDerived>
    514   inline Transform& translate(const MatrixBase<OtherDerived> &other);
    515 
    516   template<typename OtherDerived>
    517   inline Transform& pretranslate(const MatrixBase<OtherDerived> &other);
    518 
    519   template<typename RotationType>
    520   inline Transform& rotate(const RotationType& rotation);
    521 
    522   template<typename RotationType>
    523   inline Transform& prerotate(const RotationType& rotation);
    524 
    525   Transform& shear(const Scalar& sx, const Scalar& sy);
    526   Transform& preshear(const Scalar& sx, const Scalar& sy);
    527 
    528   inline Transform& operator=(const TranslationType& t);
    529   inline Transform& operator*=(const TranslationType& t) { return translate(t.vector()); }
    530   inline Transform operator*(const TranslationType& t) const;
    531 
    532   inline Transform& operator=(const UniformScaling<Scalar>& t);
    533   inline Transform& operator*=(const UniformScaling<Scalar>& s) { return scale(s.factor()); }
    534   inline Transform<Scalar,Dim,(int(Mode)==int(Isometry)?int(Affine):int(Mode))> operator*(const UniformScaling<Scalar>& s) const
    535   {
    536     Transform<Scalar,Dim,(int(Mode)==int(Isometry)?int(Affine):int(Mode)),Options> res = *this;
    537     res.scale(s.factor());
    538     return res;
    539   }
    540 
    541   inline Transform& operator*=(const DiagonalMatrix<Scalar,Dim>& s) { linear() *= s; return *this; }
    542 
    543   template<typename Derived>
    544   inline Transform& operator=(const RotationBase<Derived,Dim>& r);
    545   template<typename Derived>
    546   inline Transform& operator*=(const RotationBase<Derived,Dim>& r) { return rotate(r.toRotationMatrix()); }
    547   template<typename Derived>
    548   inline Transform operator*(const RotationBase<Derived,Dim>& r) const;
    549 
    550   const LinearMatrixType rotation() const;
    551   template<typename RotationMatrixType, typename ScalingMatrixType>
    552   void computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const;
    553   template<typename ScalingMatrixType, typename RotationMatrixType>
    554   void computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const;
    555 
    556   template<typename PositionDerived, typename OrientationType, typename ScaleDerived>
    557   Transform& fromPositionOrientationScale(const MatrixBase<PositionDerived> &position,
    558     const OrientationType& orientation, const MatrixBase<ScaleDerived> &scale);
    559 
    560   inline Transform inverse(TransformTraits traits = (TransformTraits)Mode) const;
    561 
    562   /** \returns a const pointer to the column major internal matrix */
    563   const Scalar* data() const { return m_matrix.data(); }
    564   /** \returns a non-const pointer to the column major internal matrix */
    565   Scalar* data() { return m_matrix.data(); }
    566 
    567   /** \returns \c *this with scalar type casted to \a NewScalarType
    568     *
    569     * Note that if \a NewScalarType is equal to the current scalar type of \c *this
    570     * then this function smartly returns a const reference to \c *this.
    571     */
    572   template<typename NewScalarType>
    573   inline typename internal::cast_return_type<Transform,Transform<NewScalarType,Dim,Mode,Options> >::type cast() const
    574   { return typename internal::cast_return_type<Transform,Transform<NewScalarType,Dim,Mode,Options> >::type(*this); }
    575 
    576   /** Copy constructor with scalar type conversion */
    577   template<typename OtherScalarType>
    578   inline explicit Transform(const Transform<OtherScalarType,Dim,Mode,Options>& other)
    579   {
    580     check_template_params();
    581     m_matrix = other.matrix().template cast<Scalar>();
    582   }
    583 
    584   /** \returns \c true if \c *this is approximately equal to \a other, within the precision
    585     * determined by \a prec.
    586     *
    587     * \sa MatrixBase::isApprox() */
    588   bool isApprox(const Transform& other, const typename NumTraits<Scalar>::Real& prec = NumTraits<Scalar>::dummy_precision()) const
    589   { return m_matrix.isApprox(other.m_matrix, prec); }
    590 
    591   /** Sets the last row to [0 ... 0 1]
    592     */
    593   void makeAffine()
    594   {
    595     internal::transform_make_affine<int(Mode)>::run(m_matrix);
    596   }
    597 
    598   /** \internal
    599     * \returns the Dim x Dim linear part if the transformation is affine,
    600     *          and the HDim x Dim part for projective transformations.
    601     */
    602   inline Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,Dim> linearExt()
    603   { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,Dim>(0,0); }
    604   /** \internal
    605     * \returns the Dim x Dim linear part if the transformation is affine,
    606     *          and the HDim x Dim part for projective transformations.
    607     */
    608   inline const Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,Dim> linearExt() const
    609   { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,Dim>(0,0); }
    610 
    611   /** \internal
    612     * \returns the translation part if the transformation is affine,
    613     *          and the last column for projective transformations.
    614     */
    615   inline Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,1> translationExt()
    616   { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,1>(0,Dim); }
    617   /** \internal
    618     * \returns the translation part if the transformation is affine,
    619     *          and the last column for projective transformations.
    620     */
    621   inline const Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,1> translationExt() const
    622   { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,1>(0,Dim); }
    623 
    624 
    625   #ifdef EIGEN_TRANSFORM_PLUGIN
    626   #include EIGEN_TRANSFORM_PLUGIN
    627   #endif
    628 
    629 protected:
    630   #ifndef EIGEN_PARSED_BY_DOXYGEN
    631     static EIGEN_STRONG_INLINE void check_template_params()
    632     {
    633       EIGEN_STATIC_ASSERT((Options & (DontAlign|RowMajor)) == Options, INVALID_MATRIX_TEMPLATE_PARAMETERS)
    634     }
    635   #endif
    636 
    637 };
    638 
    639 /** \ingroup Geometry_Module */
    640 typedef Transform<float,2,Isometry> Isometry2f;
    641 /** \ingroup Geometry_Module */
    642 typedef Transform<float,3,Isometry> Isometry3f;
    643 /** \ingroup Geometry_Module */
    644 typedef Transform<double,2,Isometry> Isometry2d;
    645 /** \ingroup Geometry_Module */
    646 typedef Transform<double,3,Isometry> Isometry3d;
    647 
    648 /** \ingroup Geometry_Module */
    649 typedef Transform<float,2,Affine> Affine2f;
    650 /** \ingroup Geometry_Module */
    651 typedef Transform<float,3,Affine> Affine3f;
    652 /** \ingroup Geometry_Module */
    653 typedef Transform<double,2,Affine> Affine2d;
    654 /** \ingroup Geometry_Module */
    655 typedef Transform<double,3,Affine> Affine3d;
    656 
    657 /** \ingroup Geometry_Module */
    658 typedef Transform<float,2,AffineCompact> AffineCompact2f;
    659 /** \ingroup Geometry_Module */
    660 typedef Transform<float,3,AffineCompact> AffineCompact3f;
    661 /** \ingroup Geometry_Module */
    662 typedef Transform<double,2,AffineCompact> AffineCompact2d;
    663 /** \ingroup Geometry_Module */
    664 typedef Transform<double,3,AffineCompact> AffineCompact3d;
    665 
    666 /** \ingroup Geometry_Module */
    667 typedef Transform<float,2,Projective> Projective2f;
    668 /** \ingroup Geometry_Module */
    669 typedef Transform<float,3,Projective> Projective3f;
    670 /** \ingroup Geometry_Module */
    671 typedef Transform<double,2,Projective> Projective2d;
    672 /** \ingroup Geometry_Module */
    673 typedef Transform<double,3,Projective> Projective3d;
    674 
    675 /**************************
    676 *** Optional QT support ***
    677 **************************/
    678 
    679 #ifdef EIGEN_QT_SUPPORT
    680 /** Initializes \c *this from a QMatrix assuming the dimension is 2.
    681   *
    682   * This function is available only if the token EIGEN_QT_SUPPORT is defined.
    683   */
    684 template<typename Scalar, int Dim, int Mode,int Options>
    685 Transform<Scalar,Dim,Mode,Options>::Transform(const QMatrix& other)
    686 {
    687   check_template_params();
    688   *this = other;
    689 }
    690 
    691 /** Set \c *this from a QMatrix assuming the dimension is 2.
    692   *
    693   * This function is available only if the token EIGEN_QT_SUPPORT is defined.
    694   */
    695 template<typename Scalar, int Dim, int Mode,int Options>
    696 Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const QMatrix& other)
    697 {
    698   EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
    699   m_matrix << other.m11(), other.m21(), other.dx(),
    700               other.m12(), other.m22(), other.dy(),
    701               0, 0, 1;
    702   return *this;
    703 }
    704 
    705 /** \returns a QMatrix from \c *this assuming the dimension is 2.
    706   *
    707   * \warning this conversion might loss data if \c *this is not affine
    708   *
    709   * This function is available only if the token EIGEN_QT_SUPPORT is defined.
    710   */
    711 template<typename Scalar, int Dim, int Mode, int Options>
    712 QMatrix Transform<Scalar,Dim,Mode,Options>::toQMatrix(void) const
    713 {
    714   check_template_params();
    715   EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
    716   return QMatrix(m_matrix.coeff(0,0), m_matrix.coeff(1,0),
    717                  m_matrix.coeff(0,1), m_matrix.coeff(1,1),
    718                  m_matrix.coeff(0,2), m_matrix.coeff(1,2));
    719 }
    720 
    721 /** Initializes \c *this from a QTransform assuming the dimension is 2.
    722   *
    723   * This function is available only if the token EIGEN_QT_SUPPORT is defined.
    724   */
    725 template<typename Scalar, int Dim, int Mode,int Options>
    726 Transform<Scalar,Dim,Mode,Options>::Transform(const QTransform& other)
    727 {
    728   check_template_params();
    729   *this = other;
    730 }
    731 
    732 /** Set \c *this from a QTransform assuming the dimension is 2.
    733   *
    734   * This function is available only if the token EIGEN_QT_SUPPORT is defined.
    735   */
    736 template<typename Scalar, int Dim, int Mode, int Options>
    737 Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const QTransform& other)
    738 {
    739   check_template_params();
    740   EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
    741   if (Mode == int(AffineCompact))
    742     m_matrix << other.m11(), other.m21(), other.dx(),
    743                 other.m12(), other.m22(), other.dy();
    744   else
    745     m_matrix << other.m11(), other.m21(), other.dx(),
    746                 other.m12(), other.m22(), other.dy(),
    747                 other.m13(), other.m23(), other.m33();
    748   return *this;
    749 }
    750 
    751 /** \returns a QTransform from \c *this assuming the dimension is 2.
    752   *
    753   * This function is available only if the token EIGEN_QT_SUPPORT is defined.
    754   */
    755 template<typename Scalar, int Dim, int Mode, int Options>
    756 QTransform Transform<Scalar,Dim,Mode,Options>::toQTransform(void) const
    757 {
    758   EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
    759   if (Mode == int(AffineCompact))
    760     return QTransform(m_matrix.coeff(0,0), m_matrix.coeff(1,0),
    761                       m_matrix.coeff(0,1), m_matrix.coeff(1,1),
    762                       m_matrix.coeff(0,2), m_matrix.coeff(1,2));
    763   else
    764     return QTransform(m_matrix.coeff(0,0), m_matrix.coeff(1,0), m_matrix.coeff(2,0),
    765                       m_matrix.coeff(0,1), m_matrix.coeff(1,1), m_matrix.coeff(2,1),
    766                       m_matrix.coeff(0,2), m_matrix.coeff(1,2), m_matrix.coeff(2,2));
    767 }
    768 #endif
    769 
    770 /*********************
    771 *** Procedural API ***
    772 *********************/
    773 
    774 /** Applies on the right the non uniform scale transformation represented
    775   * by the vector \a other to \c *this and returns a reference to \c *this.
    776   * \sa prescale()
    777   */
    778 template<typename Scalar, int Dim, int Mode, int Options>
    779 template<typename OtherDerived>
    780 Transform<Scalar,Dim,Mode,Options>&
    781 Transform<Scalar,Dim,Mode,Options>::scale(const MatrixBase<OtherDerived> &other)
    782 {
    783   EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
    784   EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
    785   linearExt().noalias() = (linearExt() * other.asDiagonal());
    786   return *this;
    787 }
    788 
    789 /** Applies on the right a uniform scale of a factor \a c to \c *this
    790   * and returns a reference to \c *this.
    791   * \sa prescale(Scalar)
    792   */
    793 template<typename Scalar, int Dim, int Mode, int Options>
    794 inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::scale(const Scalar& s)
    795 {
    796   EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
    797   linearExt() *= s;
    798   return *this;
    799 }
    800 
    801 /** Applies on the left the non uniform scale transformation represented
    802   * by the vector \a other to \c *this and returns a reference to \c *this.
    803   * \sa scale()
    804   */
    805 template<typename Scalar, int Dim, int Mode, int Options>
    806 template<typename OtherDerived>
    807 Transform<Scalar,Dim,Mode,Options>&
    808 Transform<Scalar,Dim,Mode,Options>::prescale(const MatrixBase<OtherDerived> &other)
    809 {
    810   EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
    811   EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
    812   m_matrix.template block<Dim,HDim>(0,0).noalias() = (other.asDiagonal() * m_matrix.template block<Dim,HDim>(0,0));
    813   return *this;
    814 }
    815 
    816 /** Applies on the left a uniform scale of a factor \a c to \c *this
    817   * and returns a reference to \c *this.
    818   * \sa scale(Scalar)
    819   */
    820 template<typename Scalar, int Dim, int Mode, int Options>
    821 inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::prescale(const Scalar& s)
    822 {
    823   EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
    824   m_matrix.template topRows<Dim>() *= s;
    825   return *this;
    826 }
    827 
    828 /** Applies on the right the translation matrix represented by the vector \a other
    829   * to \c *this and returns a reference to \c *this.
    830   * \sa pretranslate()
    831   */
    832 template<typename Scalar, int Dim, int Mode, int Options>
    833 template<typename OtherDerived>
    834 Transform<Scalar,Dim,Mode,Options>&
    835 Transform<Scalar,Dim,Mode,Options>::translate(const MatrixBase<OtherDerived> &other)
    836 {
    837   EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
    838   translationExt() += linearExt() * other;
    839   return *this;
    840 }
    841 
    842 /** Applies on the left the translation matrix represented by the vector \a other
    843   * to \c *this and returns a reference to \c *this.
    844   * \sa translate()
    845   */
    846 template<typename Scalar, int Dim, int Mode, int Options>
    847 template<typename OtherDerived>
    848 Transform<Scalar,Dim,Mode,Options>&
    849 Transform<Scalar,Dim,Mode,Options>::pretranslate(const MatrixBase<OtherDerived> &other)
    850 {
    851   EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
    852   if(int(Mode)==int(Projective))
    853     affine() += other * m_matrix.row(Dim);
    854   else
    855     translation() += other;
    856   return *this;
    857 }
    858 
    859 /** Applies on the right the rotation represented by the rotation \a rotation
    860   * to \c *this and returns a reference to \c *this.
    861   *
    862   * The template parameter \a RotationType is the type of the rotation which
    863   * must be known by internal::toRotationMatrix<>.
    864   *
    865   * Natively supported types includes:
    866   *   - any scalar (2D),
    867   *   - a Dim x Dim matrix expression,
    868   *   - a Quaternion (3D),
    869   *   - a AngleAxis (3D)
    870   *
    871   * This mechanism is easily extendable to support user types such as Euler angles,
    872   * or a pair of Quaternion for 4D rotations.
    873   *
    874   * \sa rotate(Scalar), class Quaternion, class AngleAxis, prerotate(RotationType)
    875   */
    876 template<typename Scalar, int Dim, int Mode, int Options>
    877 template<typename RotationType>
    878 Transform<Scalar,Dim,Mode,Options>&
    879 Transform<Scalar,Dim,Mode,Options>::rotate(const RotationType& rotation)
    880 {
    881   linearExt() *= internal::toRotationMatrix<Scalar,Dim>(rotation);
    882   return *this;
    883 }
    884 
    885 /** Applies on the left the rotation represented by the rotation \a rotation
    886   * to \c *this and returns a reference to \c *this.
    887   *
    888   * See rotate() for further details.
    889   *
    890   * \sa rotate()
    891   */
    892 template<typename Scalar, int Dim, int Mode, int Options>
    893 template<typename RotationType>
    894 Transform<Scalar,Dim,Mode,Options>&
    895 Transform<Scalar,Dim,Mode,Options>::prerotate(const RotationType& rotation)
    896 {
    897   m_matrix.template block<Dim,HDim>(0,0) = internal::toRotationMatrix<Scalar,Dim>(rotation)
    898                                          * m_matrix.template block<Dim,HDim>(0,0);
    899   return *this;
    900 }
    901 
    902 /** Applies on the right the shear transformation represented
    903   * by the vector \a other to \c *this and returns a reference to \c *this.
    904   * \warning 2D only.
    905   * \sa preshear()
    906   */
    907 template<typename Scalar, int Dim, int Mode, int Options>
    908 Transform<Scalar,Dim,Mode,Options>&
    909 Transform<Scalar,Dim,Mode,Options>::shear(const Scalar& sx, const Scalar& sy)
    910 {
    911   EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
    912   EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
    913   VectorType tmp = linear().col(0)*sy + linear().col(1);
    914   linear() << linear().col(0) + linear().col(1)*sx, tmp;
    915   return *this;
    916 }
    917 
    918 /** Applies on the left the shear transformation represented
    919   * by the vector \a other to \c *this and returns a reference to \c *this.
    920   * \warning 2D only.
    921   * \sa shear()
    922   */
    923 template<typename Scalar, int Dim, int Mode, int Options>
    924 Transform<Scalar,Dim,Mode,Options>&
    925 Transform<Scalar,Dim,Mode,Options>::preshear(const Scalar& sx, const Scalar& sy)
    926 {
    927   EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
    928   EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
    929   m_matrix.template block<Dim,HDim>(0,0) = LinearMatrixType(1, sx, sy, 1) * m_matrix.template block<Dim,HDim>(0,0);
    930   return *this;
    931 }
    932 
    933 /******************************************************
    934 *** Scaling, Translation and Rotation compatibility ***
    935 ******************************************************/
    936 
    937 template<typename Scalar, int Dim, int Mode, int Options>
    938 inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const TranslationType& t)
    939 {
    940   linear().setIdentity();
    941   translation() = t.vector();
    942   makeAffine();
    943   return *this;
    944 }
    945 
    946 template<typename Scalar, int Dim, int Mode, int Options>
    947 inline Transform<Scalar,Dim,Mode,Options> Transform<Scalar,Dim,Mode,Options>::operator*(const TranslationType& t) const
    948 {
    949   Transform res = *this;
    950   res.translate(t.vector());
    951   return res;
    952 }
    953 
    954 template<typename Scalar, int Dim, int Mode, int Options>
    955 inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const UniformScaling<Scalar>& s)
    956 {
    957   m_matrix.setZero();
    958   linear().diagonal().fill(s.factor());
    959   makeAffine();
    960   return *this;
    961 }
    962 
    963 template<typename Scalar, int Dim, int Mode, int Options>
    964 template<typename Derived>
    965 inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const RotationBase<Derived,Dim>& r)
    966 {
    967   linear() = internal::toRotationMatrix<Scalar,Dim>(r);
    968   translation().setZero();
    969   makeAffine();
    970   return *this;
    971 }
    972 
    973 template<typename Scalar, int Dim, int Mode, int Options>
    974 template<typename Derived>
    975 inline Transform<Scalar,Dim,Mode,Options> Transform<Scalar,Dim,Mode,Options>::operator*(const RotationBase<Derived,Dim>& r) const
    976 {
    977   Transform res = *this;
    978   res.rotate(r.derived());
    979   return res;
    980 }
    981 
    982 /************************
    983 *** Special functions ***
    984 ************************/
    985 
    986 /** \returns the rotation part of the transformation
    987   *
    988   *
    989   * \svd_module
    990   *
    991   * \sa computeRotationScaling(), computeScalingRotation(), class SVD
    992   */
    993 template<typename Scalar, int Dim, int Mode, int Options>
    994 const typename Transform<Scalar,Dim,Mode,Options>::LinearMatrixType
    995 Transform<Scalar,Dim,Mode,Options>::rotation() const
    996 {
    997   LinearMatrixType result;
    998   computeRotationScaling(&result, (LinearMatrixType*)0);
    999   return result;
   1000 }
   1001 
   1002 
   1003 /** decomposes the linear part of the transformation as a product rotation x scaling, the scaling being
   1004   * not necessarily positive.
   1005   *
   1006   * If either pointer is zero, the corresponding computation is skipped.
   1007   *
   1008   *
   1009   *
   1010   * \svd_module
   1011   *
   1012   * \sa computeScalingRotation(), rotation(), class SVD
   1013   */
   1014 template<typename Scalar, int Dim, int Mode, int Options>
   1015 template<typename RotationMatrixType, typename ScalingMatrixType>
   1016 void Transform<Scalar,Dim,Mode,Options>::computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const
   1017 {
   1018   JacobiSVD<LinearMatrixType> svd(linear(), ComputeFullU | ComputeFullV);
   1019 
   1020   Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant(); // so x has absolute value 1
   1021   VectorType sv(svd.singularValues());
   1022   sv.coeffRef(0) *= x;
   1023   if(scaling) scaling->lazyAssign(svd.matrixV() * sv.asDiagonal() * svd.matrixV().adjoint());
   1024   if(rotation)
   1025   {
   1026     LinearMatrixType m(svd.matrixU());
   1027     m.col(0) /= x;
   1028     rotation->lazyAssign(m * svd.matrixV().adjoint());
   1029   }
   1030 }
   1031 
   1032 /** decomposes the linear part of the transformation as a product rotation x scaling, the scaling being
   1033   * not necessarily positive.
   1034   *
   1035   * If either pointer is zero, the corresponding computation is skipped.
   1036   *
   1037   *
   1038   *
   1039   * \svd_module
   1040   *
   1041   * \sa computeRotationScaling(), rotation(), class SVD
   1042   */
   1043 template<typename Scalar, int Dim, int Mode, int Options>
   1044 template<typename ScalingMatrixType, typename RotationMatrixType>
   1045 void Transform<Scalar,Dim,Mode,Options>::computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const
   1046 {
   1047   JacobiSVD<LinearMatrixType> svd(linear(), ComputeFullU | ComputeFullV);
   1048 
   1049   Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant(); // so x has absolute value 1
   1050   VectorType sv(svd.singularValues());
   1051   sv.coeffRef(0) *= x;
   1052   if(scaling) scaling->lazyAssign(svd.matrixU() * sv.asDiagonal() * svd.matrixU().adjoint());
   1053   if(rotation)
   1054   {
   1055     LinearMatrixType m(svd.matrixU());
   1056     m.col(0) /= x;
   1057     rotation->lazyAssign(m * svd.matrixV().adjoint());
   1058   }
   1059 }
   1060 
   1061 /** Convenient method to set \c *this from a position, orientation and scale
   1062   * of a 3D object.
   1063   */
   1064 template<typename Scalar, int Dim, int Mode, int Options>
   1065 template<typename PositionDerived, typename OrientationType, typename ScaleDerived>
   1066 Transform<Scalar,Dim,Mode,Options>&
   1067 Transform<Scalar,Dim,Mode,Options>::fromPositionOrientationScale(const MatrixBase<PositionDerived> &position,
   1068   const OrientationType& orientation, const MatrixBase<ScaleDerived> &scale)
   1069 {
   1070   linear() = internal::toRotationMatrix<Scalar,Dim>(orientation);
   1071   linear() *= scale.asDiagonal();
   1072   translation() = position;
   1073   makeAffine();
   1074   return *this;
   1075 }
   1076 
   1077 namespace internal {
   1078 
   1079 template<int Mode>
   1080 struct transform_make_affine
   1081 {
   1082   template<typename MatrixType>
   1083   static void run(MatrixType &mat)
   1084   {
   1085     static const int Dim = MatrixType::ColsAtCompileTime-1;
   1086     mat.template block<1,Dim>(Dim,0).setZero();
   1087     mat.coeffRef(Dim,Dim) = typename MatrixType::Scalar(1);
   1088   }
   1089 };
   1090 
   1091 template<>
   1092 struct transform_make_affine<AffineCompact>
   1093 {
   1094   template<typename MatrixType> static void run(MatrixType &) { }
   1095 };
   1096 
   1097 // selector needed to avoid taking the inverse of a 3x4 matrix
   1098 template<typename TransformType, int Mode=TransformType::Mode>
   1099 struct projective_transform_inverse
   1100 {
   1101   static inline void run(const TransformType&, TransformType&)
   1102   {}
   1103 };
   1104 
   1105 template<typename TransformType>
   1106 struct projective_transform_inverse<TransformType, Projective>
   1107 {
   1108   static inline void run(const TransformType& m, TransformType& res)
   1109   {
   1110     res.matrix() = m.matrix().inverse();
   1111   }
   1112 };
   1113 
   1114 } // end namespace internal
   1115 
   1116 
   1117 /**
   1118   *
   1119   * \returns the inverse transformation according to some given knowledge
   1120   * on \c *this.
   1121   *
   1122   * \param hint allows to optimize the inversion process when the transformation
   1123   * is known to be not a general transformation (optional). The possible values are:
   1124   *  - #Projective if the transformation is not necessarily affine, i.e., if the
   1125   *    last row is not guaranteed to be [0 ... 0 1]
   1126   *  - #Affine if the last row can be assumed to be [0 ... 0 1]
   1127   *  - #Isometry if the transformation is only a concatenations of translations
   1128   *    and rotations.
   1129   *  The default is the template class parameter \c Mode.
   1130   *
   1131   * \warning unless \a traits is always set to NoShear or NoScaling, this function
   1132   * requires the generic inverse method of MatrixBase defined in the LU module. If
   1133   * you forget to include this module, then you will get hard to debug linking errors.
   1134   *
   1135   * \sa MatrixBase::inverse()
   1136   */
   1137 template<typename Scalar, int Dim, int Mode, int Options>
   1138 Transform<Scalar,Dim,Mode,Options>
   1139 Transform<Scalar,Dim,Mode,Options>::inverse(TransformTraits hint) const
   1140 {
   1141   Transform res;
   1142   if (hint == Projective)
   1143   {
   1144     internal::projective_transform_inverse<Transform>::run(*this, res);
   1145   }
   1146   else
   1147   {
   1148     if (hint == Isometry)
   1149     {
   1150       res.matrix().template topLeftCorner<Dim,Dim>() = linear().transpose();
   1151     }
   1152     else if(hint&Affine)
   1153     {
   1154       res.matrix().template topLeftCorner<Dim,Dim>() = linear().inverse();
   1155     }
   1156     else
   1157     {
   1158       eigen_assert(false && "Invalid transform traits in Transform::Inverse");
   1159     }
   1160     // translation and remaining parts
   1161     res.matrix().template topRightCorner<Dim,1>()
   1162       = - res.matrix().template topLeftCorner<Dim,Dim>() * translation();
   1163     res.makeAffine(); // we do need this, because in the beginning res is uninitialized
   1164   }
   1165   return res;
   1166 }
   1167 
   1168 namespace internal {
   1169 
   1170 /*****************************************************
   1171 *** Specializations of take affine part            ***
   1172 *****************************************************/
   1173 
   1174 template<typename TransformType> struct transform_take_affine_part {
   1175   typedef typename TransformType::MatrixType MatrixType;
   1176   typedef typename TransformType::AffinePart AffinePart;
   1177   typedef typename TransformType::ConstAffinePart ConstAffinePart;
   1178   static inline AffinePart run(MatrixType& m)
   1179   { return m.template block<TransformType::Dim,TransformType::HDim>(0,0); }
   1180   static inline ConstAffinePart run(const MatrixType& m)
   1181   { return m.template block<TransformType::Dim,TransformType::HDim>(0,0); }
   1182 };
   1183 
   1184 template<typename Scalar, int Dim, int Options>
   1185 struct transform_take_affine_part<Transform<Scalar,Dim,AffineCompact, Options> > {
   1186   typedef typename Transform<Scalar,Dim,AffineCompact,Options>::MatrixType MatrixType;
   1187   static inline MatrixType& run(MatrixType& m) { return m; }
   1188   static inline const MatrixType& run(const MatrixType& m) { return m; }
   1189 };
   1190 
   1191 /*****************************************************
   1192 *** Specializations of construct from matrix       ***
   1193 *****************************************************/
   1194 
   1195 template<typename Other, int Mode, int Options, int Dim, int HDim>
   1196 struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, Dim,Dim>
   1197 {
   1198   static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other)
   1199   {
   1200     transform->linear() = other;
   1201     transform->translation().setZero();
   1202     transform->makeAffine();
   1203   }
   1204 };
   1205 
   1206 template<typename Other, int Mode, int Options, int Dim, int HDim>
   1207 struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, Dim,HDim>
   1208 {
   1209   static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other)
   1210   {
   1211     transform->affine() = other;
   1212     transform->makeAffine();
   1213   }
   1214 };
   1215 
   1216 template<typename Other, int Mode, int Options, int Dim, int HDim>
   1217 struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, HDim,HDim>
   1218 {
   1219   static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other)
   1220   { transform->matrix() = other; }
   1221 };
   1222 
   1223 template<typename Other, int Options, int Dim, int HDim>
   1224 struct transform_construct_from_matrix<Other, AffineCompact,Options,Dim,HDim, HDim,HDim>
   1225 {
   1226   static inline void run(Transform<typename Other::Scalar,Dim,AffineCompact,Options> *transform, const Other& other)
   1227   { transform->matrix() = other.template block<Dim,HDim>(0,0); }
   1228 };
   1229 
   1230 /**********************************************************
   1231 ***   Specializations of operator* with rhs EigenBase   ***
   1232 **********************************************************/
   1233 
   1234 template<int LhsMode,int RhsMode>
   1235 struct transform_product_result
   1236 {
   1237   enum
   1238   {
   1239     Mode =
   1240       (LhsMode == (int)Projective    || RhsMode == (int)Projective    ) ? Projective :
   1241       (LhsMode == (int)Affine        || RhsMode == (int)Affine        ) ? Affine :
   1242       (LhsMode == (int)AffineCompact || RhsMode == (int)AffineCompact ) ? AffineCompact :
   1243       (LhsMode == (int)Isometry      || RhsMode == (int)Isometry      ) ? Isometry : Projective
   1244   };
   1245 };
   1246 
   1247 template< typename TransformType, typename MatrixType >
   1248 struct transform_right_product_impl< TransformType, MatrixType, 0 >
   1249 {
   1250   typedef typename MatrixType::PlainObject ResultType;
   1251 
   1252   static EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other)
   1253   {
   1254     return T.matrix() * other;
   1255   }
   1256 };
   1257 
   1258 template< typename TransformType, typename MatrixType >
   1259 struct transform_right_product_impl< TransformType, MatrixType, 1 >
   1260 {
   1261   enum {
   1262     Dim = TransformType::Dim,
   1263     HDim = TransformType::HDim,
   1264     OtherRows = MatrixType::RowsAtCompileTime,
   1265     OtherCols = MatrixType::ColsAtCompileTime
   1266   };
   1267 
   1268   typedef typename MatrixType::PlainObject ResultType;
   1269 
   1270   static EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other)
   1271   {
   1272     EIGEN_STATIC_ASSERT(OtherRows==HDim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);
   1273 
   1274     typedef Block<ResultType, Dim, OtherCols, int(MatrixType::RowsAtCompileTime)==Dim> TopLeftLhs;
   1275 
   1276     ResultType res(other.rows(),other.cols());
   1277     TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() = T.affine() * other;
   1278     res.row(OtherRows-1) = other.row(OtherRows-1);
   1279 
   1280     return res;
   1281   }
   1282 };
   1283 
   1284 template< typename TransformType, typename MatrixType >
   1285 struct transform_right_product_impl< TransformType, MatrixType, 2 >
   1286 {
   1287   enum {
   1288     Dim = TransformType::Dim,
   1289     HDim = TransformType::HDim,
   1290     OtherRows = MatrixType::RowsAtCompileTime,
   1291     OtherCols = MatrixType::ColsAtCompileTime
   1292   };
   1293 
   1294   typedef typename MatrixType::PlainObject ResultType;
   1295 
   1296   static EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other)
   1297   {
   1298     EIGEN_STATIC_ASSERT(OtherRows==Dim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);
   1299 
   1300     typedef Block<ResultType, Dim, OtherCols, true> TopLeftLhs;
   1301     ResultType res(Replicate<typename TransformType::ConstTranslationPart, 1, OtherCols>(T.translation(),1,other.cols()));
   1302     TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() += T.linear() * other;
   1303 
   1304     return res;
   1305   }
   1306 };
   1307 
   1308 /**********************************************************
   1309 ***   Specializations of operator* with lhs EigenBase   ***
   1310 **********************************************************/
   1311 
   1312 // generic HDim x HDim matrix * T => Projective
   1313 template<typename Other,int Mode, int Options, int Dim, int HDim>
   1314 struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, HDim,HDim>
   1315 {
   1316   typedef Transform<typename Other::Scalar,Dim,Mode,Options> TransformType;
   1317   typedef typename TransformType::MatrixType MatrixType;
   1318   typedef Transform<typename Other::Scalar,Dim,Projective,Options> ResultType;
   1319   static ResultType run(const Other& other,const TransformType& tr)
   1320   { return ResultType(other * tr.matrix()); }
   1321 };
   1322 
   1323 // generic HDim x HDim matrix * AffineCompact => Projective
   1324 template<typename Other, int Options, int Dim, int HDim>
   1325 struct transform_left_product_impl<Other,AffineCompact,Options,Dim,HDim, HDim,HDim>
   1326 {
   1327   typedef Transform<typename Other::Scalar,Dim,AffineCompact,Options> TransformType;
   1328   typedef typename TransformType::MatrixType MatrixType;
   1329   typedef Transform<typename Other::Scalar,Dim,Projective,Options> ResultType;
   1330   static ResultType run(const Other& other,const TransformType& tr)
   1331   {
   1332     ResultType res;
   1333     res.matrix().noalias() = other.template block<HDim,Dim>(0,0) * tr.matrix();
   1334     res.matrix().col(Dim) += other.col(Dim);
   1335     return res;
   1336   }
   1337 };
   1338 
   1339 // affine matrix * T
   1340 template<typename Other,int Mode, int Options, int Dim, int HDim>
   1341 struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, Dim,HDim>
   1342 {
   1343   typedef Transform<typename Other::Scalar,Dim,Mode,Options> TransformType;
   1344   typedef typename TransformType::MatrixType MatrixType;
   1345   typedef TransformType ResultType;
   1346   static ResultType run(const Other& other,const TransformType& tr)
   1347   {
   1348     ResultType res;
   1349     res.affine().noalias() = other * tr.matrix();
   1350     res.matrix().row(Dim) = tr.matrix().row(Dim);
   1351     return res;
   1352   }
   1353 };
   1354 
   1355 // affine matrix * AffineCompact
   1356 template<typename Other, int Options, int Dim, int HDim>
   1357 struct transform_left_product_impl<Other,AffineCompact,Options,Dim,HDim, Dim,HDim>
   1358 {
   1359   typedef Transform<typename Other::Scalar,Dim,AffineCompact,Options> TransformType;
   1360   typedef typename TransformType::MatrixType MatrixType;
   1361   typedef TransformType ResultType;
   1362   static ResultType run(const Other& other,const TransformType& tr)
   1363   {
   1364     ResultType res;
   1365     res.matrix().noalias() = other.template block<Dim,Dim>(0,0) * tr.matrix();
   1366     res.translation() += other.col(Dim);
   1367     return res;
   1368   }
   1369 };
   1370 
   1371 // linear matrix * T
   1372 template<typename Other,int Mode, int Options, int Dim, int HDim>
   1373 struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, Dim,Dim>
   1374 {
   1375   typedef Transform<typename Other::Scalar,Dim,Mode,Options> TransformType;
   1376   typedef typename TransformType::MatrixType MatrixType;
   1377   typedef TransformType ResultType;
   1378   static ResultType run(const Other& other, const TransformType& tr)
   1379   {
   1380     TransformType res;
   1381     if(Mode!=int(AffineCompact))
   1382       res.matrix().row(Dim) = tr.matrix().row(Dim);
   1383     res.matrix().template topRows<Dim>().noalias()
   1384       = other * tr.matrix().template topRows<Dim>();
   1385     return res;
   1386   }
   1387 };
   1388 
   1389 /**********************************************************
   1390 *** Specializations of operator* with another Transform ***
   1391 **********************************************************/
   1392 
   1393 template<typename Scalar, int Dim, int LhsMode, int LhsOptions, int RhsMode, int RhsOptions>
   1394 struct transform_transform_product_impl<Transform<Scalar,Dim,LhsMode,LhsOptions>,Transform<Scalar,Dim,RhsMode,RhsOptions>,false >
   1395 {
   1396   enum { ResultMode = transform_product_result<LhsMode,RhsMode>::Mode };
   1397   typedef Transform<Scalar,Dim,LhsMode,LhsOptions> Lhs;
   1398   typedef Transform<Scalar,Dim,RhsMode,RhsOptions> Rhs;
   1399   typedef Transform<Scalar,Dim,ResultMode,LhsOptions> ResultType;
   1400   static ResultType run(const Lhs& lhs, const Rhs& rhs)
   1401   {
   1402     ResultType res;
   1403     res.linear() = lhs.linear() * rhs.linear();
   1404     res.translation() = lhs.linear() * rhs.translation() + lhs.translation();
   1405     res.makeAffine();
   1406     return res;
   1407   }
   1408 };
   1409 
   1410 template<typename Scalar, int Dim, int LhsMode, int LhsOptions, int RhsMode, int RhsOptions>
   1411 struct transform_transform_product_impl<Transform<Scalar,Dim,LhsMode,LhsOptions>,Transform<Scalar,Dim,RhsMode,RhsOptions>,true >
   1412 {
   1413   typedef Transform<Scalar,Dim,LhsMode,LhsOptions> Lhs;
   1414   typedef Transform<Scalar,Dim,RhsMode,RhsOptions> Rhs;
   1415   typedef Transform<Scalar,Dim,Projective> ResultType;
   1416   static ResultType run(const Lhs& lhs, const Rhs& rhs)
   1417   {
   1418     return ResultType( lhs.matrix() * rhs.matrix() );
   1419   }
   1420 };
   1421 
   1422 template<typename Scalar, int Dim, int LhsOptions, int RhsOptions>
   1423 struct transform_transform_product_impl<Transform<Scalar,Dim,AffineCompact,LhsOptions>,Transform<Scalar,Dim,Projective,RhsOptions>,true >
   1424 {
   1425   typedef Transform<Scalar,Dim,AffineCompact,LhsOptions> Lhs;
   1426   typedef Transform<Scalar,Dim,Projective,RhsOptions> Rhs;
   1427   typedef Transform<Scalar,Dim,Projective> ResultType;
   1428   static ResultType run(const Lhs& lhs, const Rhs& rhs)
   1429   {
   1430     ResultType res;
   1431     res.matrix().template topRows<Dim>() = lhs.matrix() * rhs.matrix();
   1432     res.matrix().row(Dim) = rhs.matrix().row(Dim);
   1433     return res;
   1434   }
   1435 };
   1436 
   1437 template<typename Scalar, int Dim, int LhsOptions, int RhsOptions>
   1438 struct transform_transform_product_impl<Transform<Scalar,Dim,Projective,LhsOptions>,Transform<Scalar,Dim,AffineCompact,RhsOptions>,true >
   1439 {
   1440   typedef Transform<Scalar,Dim,Projective,LhsOptions> Lhs;
   1441   typedef Transform<Scalar,Dim,AffineCompact,RhsOptions> Rhs;
   1442   typedef Transform<Scalar,Dim,Projective> ResultType;
   1443   static ResultType run(const Lhs& lhs, const Rhs& rhs)
   1444   {
   1445     ResultType res(lhs.matrix().template leftCols<Dim>() * rhs.matrix());
   1446     res.matrix().col(Dim) += lhs.matrix().col(Dim);
   1447     return res;
   1448   }
   1449 };
   1450 
   1451 } // end namespace internal
   1452 
   1453 } // end namespace Eigen
   1454 
   1455 #endif // EIGEN_TRANSFORM_H
   1456