5
5
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
6
6
// Copyright (C) 2010 Hauke Heibel <hauke.heibel@gmail.com>
8
// Eigen is free software; you can redistribute it and/or
9
// modify it under the terms of the GNU Lesser General Public
10
// License as published by the Free Software Foundation; either
11
// version 3 of the License, or (at your option) any later version.
13
// Alternatively, you can redistribute it and/or
14
// modify it under the terms of the GNU General Public License as
15
// published by the Free Software Foundation; either version 2 of
16
// the License, or (at your option) any later version.
18
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
19
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
21
// GNU General Public License for more details.
23
// You should have received a copy of the GNU Lesser General Public
24
// License and a copy of the GNU General Public License along with
25
// Eigen. If not, see <http://www.gnu.org/licenses/>.
8
// This Source Code Form is subject to the terms of the Mozilla
9
// Public License v. 2.0. If a copy of the MPL was not distributed
10
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
27
12
#ifndef EIGEN_TRANSFORM_H
28
13
#define EIGEN_TRANSFORM_H
30
17
namespace internal {
32
19
template<typename Transform>
207
194
/** type of the matrix used to represent the linear part of the transformation */
208
195
typedef Matrix<Scalar,Dim,Dim,Options> LinearMatrixType;
209
196
/** type of read/write reference to the linear part of the transformation */
210
typedef Block<MatrixType,Dim,Dim> LinearPart;
197
typedef Block<MatrixType,Dim,Dim,int(Mode)==(AffineCompact)> LinearPart;
211
198
/** type of read reference to the linear part of the transformation */
212
typedef const Block<ConstMatrixType,Dim,Dim> ConstLinearPart;
199
typedef const Block<ConstMatrixType,Dim,Dim,int(Mode)==(AffineCompact)> ConstLinearPart;
213
200
/** type of read/write reference to the affine part of the transformation */
214
201
typedef typename internal::conditional<int(Mode)==int(AffineCompact),
221
208
/** type of a vector */
222
209
typedef Matrix<Scalar,Dim,1> VectorType;
223
210
/** type of a read/write reference to the translation part of the rotation */
224
typedef Block<MatrixType,Dim,1> TranslationPart;
211
typedef Block<MatrixType,Dim,1,int(Mode)==(AffineCompact)> TranslationPart;
225
212
/** type of a read reference to the translation part of the rotation */
226
typedef const Block<ConstMatrixType,Dim,1> ConstTranslationPart;
213
typedef const Block<ConstMatrixType,Dim,1,int(Mode)==(AffineCompact)> ConstTranslationPart;
227
214
/** corresponding translation type */
228
215
typedef Translation<Scalar,Dim> TranslationType;
279
266
template<typename OtherDerived>
280
267
inline explicit Transform(const EigenBase<OtherDerived>& other)
269
EIGEN_STATIC_ASSERT((internal::is_same<Scalar,typename OtherDerived::Scalar>::value),
270
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY);
282
272
check_template_params();
283
273
internal::transform_construct_from_matrix<OtherDerived,Mode,Options,Dim,HDim>::run(this, other.derived());
287
277
template<typename OtherDerived>
288
278
inline Transform& operator=(const EigenBase<OtherDerived>& other)
280
EIGEN_STATIC_ASSERT((internal::is_same<Scalar,typename OtherDerived::Scalar>::value),
281
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY);
290
283
internal::transform_construct_from_matrix<OtherDerived,Mode,Options,Dim,HDim>::run(this, other.derived());
376
369
inline MatrixType& matrix() { return m_matrix; }
378
371
/** \returns a read-only expression of the linear part of the transformation */
379
inline ConstLinearPart linear() const { return m_matrix.template block<Dim,Dim>(0,0); }
372
inline ConstLinearPart linear() const { return ConstLinearPart(m_matrix,0,0); }
380
373
/** \returns a writable expression of the linear part of the transformation */
381
inline LinearPart linear() { return m_matrix.template block<Dim,Dim>(0,0); }
374
inline LinearPart linear() { return LinearPart(m_matrix,0,0); }
383
376
/** \returns a read-only expression of the Dim x HDim affine part of the transformation */
384
377
inline ConstAffinePart affine() const { return take_affine_part::run(m_matrix); }
386
379
inline AffinePart affine() { return take_affine_part::run(m_matrix); }
388
381
/** \returns a read-only expression of the translation vector of the transformation */
389
inline ConstTranslationPart translation() const { return m_matrix.template block<Dim,1>(0,Dim); }
382
inline ConstTranslationPart translation() const { return ConstTranslationPart(m_matrix,0,Dim); }
390
383
/** \returns a writable expression of the translation vector of the transformation */
391
inline TranslationPart translation() { return m_matrix.template block<Dim,1>(0,Dim); }
384
inline TranslationPart translation() { return TranslationPart(m_matrix,0,Dim); }
393
386
/** \returns an expression of the product between the transform \c *this and a matrix expression \a other
461
454
return internal::transform_transform_product_impl<Transform,Transform>::run(*this,other);
464
/** Concatenates two different transformations */
465
template<int OtherMode,int OtherOptions>
466
inline const typename internal::transform_transform_product_impl<
467
Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> >::ResultType
457
#ifdef __INTEL_COMPILER
459
// this intermediate structure permits to workaround a bug in ICC 11:
460
// error: template instantiation resulted in unexpected function type of "Eigen::Transform<double, 3, 32, 0>
461
// (const Eigen::Transform<double, 3, 2, 0> &) const"
462
// (the meaning of a name may have changed since the template declaration -- the type of the template is:
463
// "Eigen::internal::transform_transform_product_impl<Eigen::Transform<double, 3, 32, 0>,
464
// Eigen::Transform<double, 3, Mode, Options>, <expression>>::ResultType (const Eigen::Transform<double, 3, Mode, Options> &) const")
466
template<int OtherMode,int OtherOptions> struct icc_11_workaround
468
typedef internal::transform_transform_product_impl<Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> > ProductType;
469
typedef typename ProductType::ResultType ResultType;
473
/** Concatenates two different transformations */
474
template<int OtherMode,int OtherOptions>
475
inline typename icc_11_workaround<OtherMode,OtherOptions>::ResultType
476
operator * (const Transform<Scalar,Dim,OtherMode,OtherOptions>& other) const
478
typedef typename icc_11_workaround<OtherMode,OtherOptions>::ProductType ProductType;
479
return ProductType::run(*this,other);
482
/** Concatenates two different transformations */
483
template<int OtherMode,int OtherOptions>
484
inline typename internal::transform_transform_product_impl<Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> >::ResultType
468
485
operator * (const Transform<Scalar,Dim,OtherMode,OtherOptions>& other) const
470
487
return internal::transform_transform_product_impl<Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> >::run(*this,other);
473
491
/** \sa MatrixBase::setIdentity() */
474
492
void setIdentity() { m_matrix.setIdentity(); }
513
531
inline Transform& operator=(const UniformScaling<Scalar>& t);
514
532
inline Transform& operator*=(const UniformScaling<Scalar>& s) { return scale(s.factor()); }
515
inline Transform operator*(const UniformScaling<Scalar>& s) const;
533
inline Transform<Scalar,Dim,(int(Mode)==int(Isometry)?Affine:Isometry)> operator*(const UniformScaling<Scalar>& s) const
535
Transform<Scalar,Dim,(int(Mode)==int(Isometry)?Affine:Isometry),Options> res = *this;
536
res.scale(s.factor());
517
540
inline Transform& operator*=(const DiagonalMatrix<Scalar,Dim>& s) { linear() *= s; return *this; }
943
966
template<typename Scalar, int Dim, int Mode, int Options>
944
inline Transform<Scalar,Dim,Mode,Options> Transform<Scalar,Dim,Mode,Options>::operator*(const UniformScaling<Scalar>& s) const
946
Transform res = *this;
947
res.scale(s.factor());
951
template<typename Scalar, int Dim, int Mode, int Options>
952
967
template<typename Derived>
953
968
inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const RotationBase<Derived,Dim>& r)
1238
1253
typedef typename MatrixType::PlainObject ResultType;
1240
EIGEN_STRONG_INLINE static ResultType run(const TransformType& T, const MatrixType& other)
1255
static EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other)
1242
1257
EIGEN_STATIC_ASSERT(OtherRows==HDim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);
1244
typedef Block<ResultType, Dim, OtherCols> TopLeftLhs;
1259
typedef Block<ResultType, Dim, OtherCols, int(MatrixType::RowsAtCompileTime)==Dim> TopLeftLhs;
1246
1261
ResultType res(other.rows(),other.cols());
1247
1262
TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() = T.affine() * other;
1264
1279
typedef typename MatrixType::PlainObject ResultType;
1266
EIGEN_STRONG_INLINE static ResultType run(const TransformType& T, const MatrixType& other)
1281
static EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other)
1268
1283
EIGEN_STATIC_ASSERT(OtherRows==Dim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);
1270
typedef Block<ResultType, Dim, OtherCols> TopLeftLhs;
1272
ResultType res(other.rows(),other.cols());
1273
TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() = T.linear() * other;
1274
TopLeftLhs(res, 0, 0, Dim, other.cols()).colwise() += T.translation();
1285
typedef Block<ResultType, Dim, OtherCols, true> TopLeftLhs;
1286
ResultType res(Replicate<typename TransformType::ConstTranslationPart, 1, OtherCols>(T.translation(),1,other.cols()));
1287
TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() += T.linear() * other;
1407
template<typename Scalar, int Dim, int LhsOptions, int RhsOptions>
1408
struct transform_transform_product_impl<Transform<Scalar,Dim,AffineCompact,LhsOptions>,Transform<Scalar,Dim,Projective,RhsOptions>,true >
1410
typedef Transform<Scalar,Dim,AffineCompact,LhsOptions> Lhs;
1411
typedef Transform<Scalar,Dim,Projective,RhsOptions> Rhs;
1412
typedef Transform<Scalar,Dim,Projective> ResultType;
1413
static ResultType run(const Lhs& lhs, const Rhs& rhs)
1416
res.matrix().template topRows<Dim>() = lhs.matrix() * rhs.matrix();
1417
res.matrix().row(Dim) = rhs.matrix().row(Dim);
1422
template<typename Scalar, int Dim, int LhsOptions, int RhsOptions>
1423
struct transform_transform_product_impl<Transform<Scalar,Dim,Projective,LhsOptions>,Transform<Scalar,Dim,AffineCompact,RhsOptions>,true >
1425
typedef Transform<Scalar,Dim,Projective,LhsOptions> Lhs;
1426
typedef Transform<Scalar,Dim,AffineCompact,RhsOptions> Rhs;
1427
typedef Transform<Scalar,Dim,Projective> ResultType;
1428
static ResultType run(const Lhs& lhs, const Rhs& rhs)
1430
ResultType res(lhs.matrix().template leftCols<Dim>() * rhs.matrix());
1431
res.matrix().col(Dim) += lhs.matrix().col(Dim);
1394
1436
} // end namespace internal
1438
} // end namespace Eigen
1396
1440
#endif // EIGEN_TRANSFORM_H