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