Michael Ernst Peter / Eigen
Committer:
ykuroda
Date:
Thu Oct 13 04:07:23 2016 +0000
Revision:
0:13a5d365ba16
First commint, Eigne Matrix Class Library

Who changed what in which revision?

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