Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
src/Geometry/Transform.h@0:13a5d365ba16, 2016-10-13 (annotated)
- 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?
User | Revision | Line number | New 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 |