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