00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef EIGEN_TRANSFORM_H
00013 #define EIGEN_TRANSFORM_H
00014
00015 namespace Eigen {
00016
00017 namespace internal {
00018
00019 template<typename Transform>
00020 struct transform_traits
00021 {
00022 enum
00023 {
00024 Dim = Transform::Dim,
00025 HDim = Transform::HDim,
00026 Mode = Transform::Mode,
00027 IsProjective = (int(Mode)==int(Projective))
00028 };
00029 };
00030
00031 template< typename TransformType,
00032 typename MatrixType,
00033 int Case = transform_traits<TransformType>::IsProjective ? 0
00034 : int(MatrixType::RowsAtCompileTime) == int(transform_traits<TransformType>::HDim) ? 1
00035 : 2>
00036 struct transform_right_product_impl;
00037
00038 template< typename Other,
00039 int Mode,
00040 int Options,
00041 int Dim,
00042 int HDim,
00043 int OtherRows=Other::RowsAtCompileTime,
00044 int OtherCols=Other::ColsAtCompileTime>
00045 struct transform_left_product_impl;
00046
00047 template< typename Lhs,
00048 typename Rhs,
00049 bool AnyProjective =
00050 transform_traits<Lhs>::IsProjective ||
00051 transform_traits<Rhs>::IsProjective>
00052 struct transform_transform_product_impl;
00053
00054 template< typename Other,
00055 int Mode,
00056 int Options,
00057 int Dim,
00058 int HDim,
00059 int OtherRows=Other::RowsAtCompileTime,
00060 int OtherCols=Other::ColsAtCompileTime>
00061 struct transform_construct_from_matrix;
00062
00063 template<typename TransformType> struct transform_take_affine_part;
00064
00065 template<int Mode> struct transform_make_affine;
00066
00067 }
00068
00177 template<typename _Scalar, int _Dim, int _Mode, int _Options>
00178 class Transform
00179 {
00180 public:
00181 EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_Dim==Dynamic ? Dynamic : (_Dim+1)*(_Dim+1))
00182 enum {
00183 Mode = _Mode,
00184 Options = _Options,
00185 Dim = _Dim,
00186 HDim = _Dim+1,
00187 Rows = int(Mode)==(AffineCompact) ? Dim : HDim
00188 };
00190 typedef _Scalar Scalar;
00191 typedef DenseIndex Index;
00193 typedef typename internal::make_proper_matrix_type<Scalar,Rows,HDim,Options>::type MatrixType;
00195 typedef const MatrixType ConstMatrixType;
00197 typedef Matrix<Scalar,Dim,Dim,Options> LinearMatrixType;
00199 typedef Block<MatrixType,Dim,Dim,int(Mode)==(AffineCompact) && (Options&RowMajor)==0> LinearPart;
00201 typedef const Block<ConstMatrixType,Dim,Dim,int(Mode)==(AffineCompact) && (Options&RowMajor)==0> ConstLinearPart;
00203 typedef typename internal::conditional<int(Mode)==int(AffineCompact),
00204 MatrixType&,
00205 Block<MatrixType,Dim,HDim> >::type AffinePart;
00207 typedef typename internal::conditional<int(Mode)==int(AffineCompact),
00208 const MatrixType&,
00209 const Block<const MatrixType,Dim,HDim> >::type ConstAffinePart;
00211 typedef Matrix<Scalar,Dim,1> VectorType;
00213 typedef Block<MatrixType,Dim,1,int(Mode)==(AffineCompact)> TranslationPart;
00215 typedef const Block<ConstMatrixType,Dim,1,int(Mode)==(AffineCompact)> ConstTranslationPart;
00217 typedef Translation<Scalar,Dim> TranslationType;
00218
00219
00220 enum { TransformTimeDiagonalMode = ((Mode==int(Isometry))?Affine:int(Mode)) };
00222 typedef Transform<Scalar,Dim,TransformTimeDiagonalMode> TransformTimeDiagonalReturnType;
00223
00224 protected:
00225
00226 MatrixType m_matrix;
00227
00228 public:
00229
00232 inline Transform()
00233 {
00234 check_template_params();
00235 internal::transform_make_affine<(int(Mode)==Affine) ? Affine : AffineCompact>::run(m_matrix);
00236 }
00237
00238 inline Transform(const Transform& other)
00239 {
00240 check_template_params();
00241 m_matrix = other.m_matrix;
00242 }
00243
00244 inline explicit Transform(const TranslationType& t)
00245 {
00246 check_template_params();
00247 *this = t;
00248 }
00249 inline explicit Transform(const UniformScaling<Scalar>& s)
00250 {
00251 check_template_params();
00252 *this = s;
00253 }
00254 template<typename Derived>
00255 inline explicit Transform(const RotationBase<Derived, Dim>& r)
00256 {
00257 check_template_params();
00258 *this = r;
00259 }
00260
00261 inline Transform& operator=(const Transform& other)
00262 { m_matrix = other.m_matrix; return *this; }
00263
00264 typedef internal::transform_take_affine_part<Transform> take_affine_part;
00265
00267 template<typename OtherDerived>
00268 inline explicit Transform(const EigenBase<OtherDerived>& other)
00269 {
00270 EIGEN_STATIC_ASSERT((internal::is_same<Scalar,typename OtherDerived::Scalar>::value),
00271 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY);
00272
00273 check_template_params();
00274 internal::transform_construct_from_matrix<OtherDerived,Mode,Options,Dim,HDim>::run(this, other.derived());
00275 }
00276
00278 template<typename OtherDerived>
00279 inline Transform& operator=(const EigenBase<OtherDerived>& other)
00280 {
00281 EIGEN_STATIC_ASSERT((internal::is_same<Scalar,typename OtherDerived::Scalar>::value),
00282 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY);
00283
00284 internal::transform_construct_from_matrix<OtherDerived,Mode,Options,Dim,HDim>::run(this, other.derived());
00285 return *this;
00286 }
00287
00288 template<int OtherOptions>
00289 inline Transform(const Transform<Scalar,Dim,Mode,OtherOptions>& other)
00290 {
00291 check_template_params();
00292
00293 m_matrix = other.matrix();
00294 }
00295
00296 template<int OtherMode,int OtherOptions>
00297 inline Transform(const Transform<Scalar,Dim,OtherMode,OtherOptions>& other)
00298 {
00299 check_template_params();
00300
00301
00302 EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(OtherMode==int(Projective), Mode==int(Projective)),
00303 YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION)
00304
00305
00306
00307 EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(OtherMode==int(Affine)||OtherMode==int(AffineCompact), Mode!=int(Isometry)),
00308 YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION)
00309
00310 enum { ModeIsAffineCompact = Mode == int(AffineCompact),
00311 OtherModeIsAffineCompact = OtherMode == int(AffineCompact)
00312 };
00313
00314 if(ModeIsAffineCompact == OtherModeIsAffineCompact)
00315 {
00316
00317
00318
00319 m_matrix.template block<Dim,Dim+1>(0,0) = other.matrix().template block<Dim,Dim+1>(0,0);
00320 makeAffine();
00321 }
00322 else if(OtherModeIsAffineCompact)
00323 {
00324 typedef typename Transform<Scalar,Dim,OtherMode,OtherOptions>::MatrixType OtherMatrixType;
00325 internal::transform_construct_from_matrix<OtherMatrixType,Mode,Options,Dim,HDim>::run(this, other.matrix());
00326 }
00327 else
00328 {
00329
00330
00331
00332 linear() = other.linear();
00333 translation() = other.translation();
00334 }
00335 }
00336
00337 template<typename OtherDerived>
00338 Transform(const ReturnByValue<OtherDerived>& other)
00339 {
00340 check_template_params();
00341 other.evalTo(*this);
00342 }
00343
00344 template<typename OtherDerived>
00345 Transform& operator=(const ReturnByValue<OtherDerived>& other)
00346 {
00347 other.evalTo(*this);
00348 return *this;
00349 }
00350
00351 #ifdef EIGEN_QT_SUPPORT
00352 inline Transform(const QMatrix& other);
00353 inline Transform& operator=(const QMatrix& other);
00354 inline QMatrix toQMatrix(void) const;
00355 inline Transform(const QTransform& other);
00356 inline Transform& operator=(const QTransform& other);
00357 inline QTransform toQTransform(void) const;
00358 #endif
00359
00362 inline Scalar operator() (Index row, Index col) const { return m_matrix(row,col); }
00365 inline Scalar& operator() (Index row, Index col) { return m_matrix(row,col); }
00366
00368 inline const MatrixType& matrix() const { return m_matrix; }
00370 inline MatrixType& matrix() { return m_matrix; }
00371
00373 inline ConstLinearPart linear() const { return ConstLinearPart(m_matrix,0,0); }
00375 inline LinearPart linear() { return LinearPart(m_matrix,0,0); }
00376
00378 inline ConstAffinePart affine() const { return take_affine_part::run(m_matrix); }
00380 inline AffinePart affine() { return take_affine_part::run(m_matrix); }
00381
00383 inline ConstTranslationPart translation() const { return ConstTranslationPart(m_matrix,0,Dim); }
00385 inline TranslationPart translation() { return TranslationPart(m_matrix,0,Dim); }
00386
00398
00399 template<typename OtherDerived>
00400 EIGEN_STRONG_INLINE const typename internal::transform_right_product_impl<Transform, OtherDerived>::ResultType
00401 operator * (const EigenBase<OtherDerived> &other) const
00402 { return internal::transform_right_product_impl<Transform, OtherDerived>::run(*this,other.derived()); }
00403
00411 template<typename OtherDerived> friend
00412 inline const typename internal::transform_left_product_impl<OtherDerived,Mode,Options,_Dim,_Dim+1>::ResultType
00413 operator * (const EigenBase<OtherDerived> &a, const Transform &b)
00414 { return internal::transform_left_product_impl<OtherDerived,Mode,Options,Dim,HDim>::run(a.derived(),b); }
00415
00422 template<typename DiagonalDerived>
00423 inline const TransformTimeDiagonalReturnType
00424 operator * (const DiagonalBase<DiagonalDerived> &b) const
00425 {
00426 TransformTimeDiagonalReturnType res(*this);
00427 res.linear() *= b;
00428 return res;
00429 }
00430
00437 template<typename DiagonalDerived>
00438 friend inline TransformTimeDiagonalReturnType
00439 operator * (const DiagonalBase<DiagonalDerived> &a, const Transform &b)
00440 {
00441 TransformTimeDiagonalReturnType res;
00442 res.linear().noalias() = a*b.linear();
00443 res.translation().noalias() = a*b.translation();
00444 if (Mode!=int(AffineCompact))
00445 res.matrix().row(Dim) = b.matrix().row(Dim);
00446 return res;
00447 }
00448
00449 template<typename OtherDerived>
00450 inline Transform& operator*=(const EigenBase<OtherDerived>& other) { return *this = *this * other; }
00451
00453 inline const Transform operator * (const Transform& other) const
00454 {
00455 return internal::transform_transform_product_impl<Transform,Transform>::run(*this,other);
00456 }
00457
00458 #ifdef __INTEL_COMPILER
00459 private:
00460
00461
00462
00463
00464
00465
00466
00467 template<int OtherMode,int OtherOptions> struct icc_11_workaround
00468 {
00469 typedef internal::transform_transform_product_impl<Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> > ProductType;
00470 typedef typename ProductType::ResultType ResultType;
00471 };
00472
00473 public:
00475 template<int OtherMode,int OtherOptions>
00476 inline typename icc_11_workaround<OtherMode,OtherOptions>::ResultType
00477 operator * (const Transform<Scalar,Dim,OtherMode,OtherOptions>& other) const
00478 {
00479 typedef typename icc_11_workaround<OtherMode,OtherOptions>::ProductType ProductType;
00480 return ProductType::run(*this,other);
00481 }
00482 #else
00483
00484 template<int OtherMode,int OtherOptions>
00485 inline typename internal::transform_transform_product_impl<Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> >::ResultType
00486 operator * (const Transform<Scalar,Dim,OtherMode,OtherOptions>& other) const
00487 {
00488 return internal::transform_transform_product_impl<Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> >::run(*this,other);
00489 }
00490 #endif
00491
00493 void setIdentity() { m_matrix.setIdentity(); }
00494
00499 static const Transform Identity()
00500 {
00501 return Transform(MatrixType::Identity());
00502 }
00503
00504 template<typename OtherDerived>
00505 inline Transform& scale(const MatrixBase<OtherDerived> &other);
00506
00507 template<typename OtherDerived>
00508 inline Transform& prescale(const MatrixBase<OtherDerived> &other);
00509
00510 inline Transform& scale(const Scalar& s);
00511 inline Transform& prescale(const Scalar& s);
00512
00513 template<typename OtherDerived>
00514 inline Transform& translate(const MatrixBase<OtherDerived> &other);
00515
00516 template<typename OtherDerived>
00517 inline Transform& pretranslate(const MatrixBase<OtherDerived> &other);
00518
00519 template<typename RotationType>
00520 inline Transform& rotate(const RotationType& rotation);
00521
00522 template<typename RotationType>
00523 inline Transform& prerotate(const RotationType& rotation);
00524
00525 Transform& shear(const Scalar& sx, const Scalar& sy);
00526 Transform& preshear(const Scalar& sx, const Scalar& sy);
00527
00528 inline Transform& operator=(const TranslationType& t);
00529 inline Transform& operator*=(const TranslationType& t) { return translate(t.vector()); }
00530 inline Transform operator*(const TranslationType& t) const;
00531
00532 inline Transform& operator=(const UniformScaling<Scalar>& t);
00533 inline Transform& operator*=(const UniformScaling<Scalar>& s) { return scale(s.factor()); }
00534 inline Transform<Scalar,Dim,(int(Mode)==int(Isometry)?int(Affine):int(Mode))> operator*(const UniformScaling<Scalar>& s) const
00535 {
00536 Transform<Scalar,Dim,(int(Mode)==int(Isometry)?int(Affine):int(Mode)),Options> res = *this;
00537 res.scale(s.factor());
00538 return res;
00539 }
00540
00541 inline Transform& operator*=(const DiagonalMatrix<Scalar,Dim>& s) { linear() *= s; return *this; }
00542
00543 template<typename Derived>
00544 inline Transform& operator=(const RotationBase<Derived,Dim>& r);
00545 template<typename Derived>
00546 inline Transform& operator*=(const RotationBase<Derived,Dim>& r) { return rotate(r.toRotationMatrix()); }
00547 template<typename Derived>
00548 inline Transform operator*(const RotationBase<Derived,Dim>& r) const;
00549
00550 const LinearMatrixType rotation() const;
00551 template<typename RotationMatrixType, typename ScalingMatrixType>
00552 void computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const;
00553 template<typename ScalingMatrixType, typename RotationMatrixType>
00554 void computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const;
00555
00556 template<typename PositionDerived, typename OrientationType, typename ScaleDerived>
00557 Transform& fromPositionOrientationScale(const MatrixBase<PositionDerived> &position,
00558 const OrientationType& orientation, const MatrixBase<ScaleDerived> &scale);
00559
00560 inline Transform inverse(TransformTraits traits = (TransformTraits)Mode) const;
00561
00563 const Scalar* data() const { return m_matrix.data(); }
00565 Scalar* data() { return m_matrix.data(); }
00566
00572 template<typename NewScalarType>
00573 inline typename internal::cast_return_type<Transform,Transform<NewScalarType,Dim,Mode,Options> >::type cast() const
00574 { return typename internal::cast_return_type<Transform,Transform<NewScalarType,Dim,Mode,Options> >::type(*this); }
00575
00577 template<typename OtherScalarType>
00578 inline explicit Transform(const Transform<OtherScalarType,Dim,Mode,Options>& other)
00579 {
00580 check_template_params();
00581 m_matrix = other.matrix().template cast<Scalar>();
00582 }
00583
00588 bool isApprox(const Transform& other, const typename NumTraits<Scalar>::Real& prec = NumTraits<Scalar>::dummy_precision()) const
00589 { return m_matrix.isApprox(other.m_matrix, prec); }
00590
00593 void makeAffine()
00594 {
00595 internal::transform_make_affine<int(Mode)>::run(m_matrix);
00596 }
00597
00602 inline Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,Dim> linearExt()
00603 { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,Dim>(0,0); }
00608 inline const Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,Dim> linearExt() const
00609 { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,Dim>(0,0); }
00610
00615 inline Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,1> translationExt()
00616 { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,1>(0,Dim); }
00621 inline const Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,1> translationExt() const
00622 { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,1>(0,Dim); }
00623
00624
00625 #ifdef EIGEN_TRANSFORM_PLUGIN
00626 #include EIGEN_TRANSFORM_PLUGIN
00627 #endif
00628
00629 protected:
00630 #ifndef EIGEN_PARSED_BY_DOXYGEN
00631 static EIGEN_STRONG_INLINE void check_template_params()
00632 {
00633 EIGEN_STATIC_ASSERT((Options & (DontAlign|RowMajor)) == Options, INVALID_MATRIX_TEMPLATE_PARAMETERS)
00634 }
00635 #endif
00636
00637 };
00638
00640 typedef Transform<float,2,Isometry> Isometry2f;
00642 typedef Transform<float,3,Isometry> Isometry3f;
00644 typedef Transform<double,2,Isometry> Isometry2d;
00646 typedef Transform<double,3,Isometry> Isometry3d;
00647
00649 typedef Transform<float,2,Affine> Affine2f;
00651 typedef Transform<float,3,Affine> Affine3f;
00653 typedef Transform<double,2,Affine> Affine2d;
00655 typedef Transform<double,3,Affine> Affine3d;
00656
00658 typedef Transform<float,2,AffineCompact> AffineCompact2f;
00660 typedef Transform<float,3,AffineCompact> AffineCompact3f;
00662 typedef Transform<double,2,AffineCompact> AffineCompact2d;
00664 typedef Transform<double,3,AffineCompact> AffineCompact3d;
00665
00667 typedef Transform<float,2,Projective> Projective2f;
00669 typedef Transform<float,3,Projective> Projective3f;
00671 typedef Transform<double,2,Projective> Projective2d;
00673 typedef Transform<double,3,Projective> Projective3d;
00674
00675
00676
00677
00678
00679 #ifdef EIGEN_QT_SUPPORT
00680
00684 template<typename Scalar, int Dim, int Mode,int Options>
00685 Transform<Scalar,Dim,Mode,Options>::Transform(const QMatrix& other)
00686 {
00687 check_template_params();
00688 *this = other;
00689 }
00690
00695 template<typename Scalar, int Dim, int Mode,int Options>
00696 Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const QMatrix& other)
00697 {
00698 EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00699 m_matrix << other.m11(), other.m21(), other.dx(),
00700 other.m12(), other.m22(), other.dy(),
00701 0, 0, 1;
00702 return *this;
00703 }
00704
00711 template<typename Scalar, int Dim, int Mode, int Options>
00712 QMatrix Transform<Scalar,Dim,Mode,Options>::toQMatrix(void) const
00713 {
00714 check_template_params();
00715 EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00716 return QMatrix(m_matrix.coeff(0,0), m_matrix.coeff(1,0),
00717 m_matrix.coeff(0,1), m_matrix.coeff(1,1),
00718 m_matrix.coeff(0,2), m_matrix.coeff(1,2));
00719 }
00720
00725 template<typename Scalar, int Dim, int Mode,int Options>
00726 Transform<Scalar,Dim,Mode,Options>::Transform(const QTransform& other)
00727 {
00728 check_template_params();
00729 *this = other;
00730 }
00731
00736 template<typename Scalar, int Dim, int Mode, int Options>
00737 Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const QTransform& other)
00738 {
00739 check_template_params();
00740 EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00741 if (Mode == int(AffineCompact))
00742 m_matrix << other.m11(), other.m21(), other.dx(),
00743 other.m12(), other.m22(), other.dy();
00744 else
00745 m_matrix << other.m11(), other.m21(), other.dx(),
00746 other.m12(), other.m22(), other.dy(),
00747 other.m13(), other.m23(), other.m33();
00748 return *this;
00749 }
00750
00755 template<typename Scalar, int Dim, int Mode, int Options>
00756 QTransform Transform<Scalar,Dim,Mode,Options>::toQTransform(void) const
00757 {
00758 EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00759 if (Mode == int(AffineCompact))
00760 return QTransform(m_matrix.coeff(0,0), m_matrix.coeff(1,0),
00761 m_matrix.coeff(0,1), m_matrix.coeff(1,1),
00762 m_matrix.coeff(0,2), m_matrix.coeff(1,2));
00763 else
00764 return QTransform(m_matrix.coeff(0,0), m_matrix.coeff(1,0), m_matrix.coeff(2,0),
00765 m_matrix.coeff(0,1), m_matrix.coeff(1,1), m_matrix.coeff(2,1),
00766 m_matrix.coeff(0,2), m_matrix.coeff(1,2), m_matrix.coeff(2,2));
00767 }
00768 #endif
00769
00770
00771
00772
00773
00778 template<typename Scalar, int Dim, int Mode, int Options>
00779 template<typename OtherDerived>
00780 Transform<Scalar,Dim,Mode,Options>&
00781 Transform<Scalar,Dim,Mode,Options>::scale(const MatrixBase<OtherDerived> &other)
00782 {
00783 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
00784 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
00785 linearExt().noalias() = (linearExt() * other.asDiagonal());
00786 return *this;
00787 }
00788
00793 template<typename Scalar, int Dim, int Mode, int Options>
00794 inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::scale(const Scalar& s)
00795 {
00796 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
00797 linearExt() *= s;
00798 return *this;
00799 }
00800
00805 template<typename Scalar, int Dim, int Mode, int Options>
00806 template<typename OtherDerived>
00807 Transform<Scalar,Dim,Mode,Options>&
00808 Transform<Scalar,Dim,Mode,Options>::prescale(const MatrixBase<OtherDerived> &other)
00809 {
00810 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
00811 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
00812 m_matrix.template block<Dim,HDim>(0,0).noalias() = (other.asDiagonal() * m_matrix.template block<Dim,HDim>(0,0));
00813 return *this;
00814 }
00815
00820 template<typename Scalar, int Dim, int Mode, int Options>
00821 inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::prescale(const Scalar& s)
00822 {
00823 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
00824 m_matrix.template topRows<Dim>() *= s;
00825 return *this;
00826 }
00827
00832 template<typename Scalar, int Dim, int Mode, int Options>
00833 template<typename OtherDerived>
00834 Transform<Scalar,Dim,Mode,Options>&
00835 Transform<Scalar,Dim,Mode,Options>::translate(const MatrixBase<OtherDerived> &other)
00836 {
00837 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
00838 translationExt() += linearExt() * other;
00839 return *this;
00840 }
00841
00846 template<typename Scalar, int Dim, int Mode, int Options>
00847 template<typename OtherDerived>
00848 Transform<Scalar,Dim,Mode,Options>&
00849 Transform<Scalar,Dim,Mode,Options>::pretranslate(const MatrixBase<OtherDerived> &other)
00850 {
00851 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
00852 if(int(Mode)==int(Projective))
00853 affine() += other * m_matrix.row(Dim);
00854 else
00855 translation() += other;
00856 return *this;
00857 }
00858
00876 template<typename Scalar, int Dim, int Mode, int Options>
00877 template<typename RotationType>
00878 Transform<Scalar,Dim,Mode,Options>&
00879 Transform<Scalar,Dim,Mode,Options>::rotate(const RotationType& rotation)
00880 {
00881 linearExt() *= internal::toRotationMatrix<Scalar,Dim>(rotation);
00882 return *this;
00883 }
00884
00892 template<typename Scalar, int Dim, int Mode, int Options>
00893 template<typename RotationType>
00894 Transform<Scalar,Dim,Mode,Options>&
00895 Transform<Scalar,Dim,Mode,Options>::prerotate(const RotationType& rotation)
00896 {
00897 m_matrix.template block<Dim,HDim>(0,0) = internal::toRotationMatrix<Scalar,Dim>(rotation)
00898 * m_matrix.template block<Dim,HDim>(0,0);
00899 return *this;
00900 }
00901
00907 template<typename Scalar, int Dim, int Mode, int Options>
00908 Transform<Scalar,Dim,Mode,Options>&
00909 Transform<Scalar,Dim,Mode,Options>::shear(const Scalar& sx, const Scalar& sy)
00910 {
00911 EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00912 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
00913 VectorType tmp = linear().col(0)*sy + linear().col(1);
00914 linear() << linear().col(0) + linear().col(1)*sx, tmp;
00915 return *this;
00916 }
00917
00923 template<typename Scalar, int Dim, int Mode, int Options>
00924 Transform<Scalar,Dim,Mode,Options>&
00925 Transform<Scalar,Dim,Mode,Options>::preshear(const Scalar& sx, const Scalar& sy)
00926 {
00927 EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00928 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
00929 m_matrix.template block<Dim,HDim>(0,0) = LinearMatrixType(1, sx, sy, 1) * m_matrix.template block<Dim,HDim>(0,0);
00930 return *this;
00931 }
00932
00933
00934
00935
00936
00937 template<typename Scalar, int Dim, int Mode, int Options>
00938 inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const TranslationType& t)
00939 {
00940 linear().setIdentity();
00941 translation() = t.vector();
00942 makeAffine();
00943 return *this;
00944 }
00945
00946 template<typename Scalar, int Dim, int Mode, int Options>
00947 inline Transform<Scalar,Dim,Mode,Options> Transform<Scalar,Dim,Mode,Options>::operator*(const TranslationType& t) const
00948 {
00949 Transform res = *this;
00950 res.translate(t.vector());
00951 return res;
00952 }
00953
00954 template<typename Scalar, int Dim, int Mode, int Options>
00955 inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const UniformScaling<Scalar>& s)
00956 {
00957 m_matrix.setZero();
00958 linear().diagonal().fill(s.factor());
00959 makeAffine();
00960 return *this;
00961 }
00962
00963 template<typename Scalar, int Dim, int Mode, int Options>
00964 template<typename Derived>
00965 inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const RotationBase<Derived,Dim>& r)
00966 {
00967 linear() = internal::toRotationMatrix<Scalar,Dim>(r);
00968 translation().setZero();
00969 makeAffine();
00970 return *this;
00971 }
00972
00973 template<typename Scalar, int Dim, int Mode, int Options>
00974 template<typename Derived>
00975 inline Transform<Scalar,Dim,Mode,Options> Transform<Scalar,Dim,Mode,Options>::operator*(const RotationBase<Derived,Dim>& r) const
00976 {
00977 Transform res = *this;
00978 res.rotate(r.derived());
00979 return res;
00980 }
00981
00982
00983
00984
00985
00993 template<typename Scalar, int Dim, int Mode, int Options>
00994 const typename Transform<Scalar,Dim,Mode,Options>::LinearMatrixType
00995 Transform<Scalar,Dim,Mode,Options>::rotation() const
00996 {
00997 LinearMatrixType result;
00998 computeRotationScaling(&result, (LinearMatrixType*)0);
00999 return result;
01000 }
01001
01002
01014 template<typename Scalar, int Dim, int Mode, int Options>
01015 template<typename RotationMatrixType, typename ScalingMatrixType>
01016 void Transform<Scalar,Dim,Mode,Options>::computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const
01017 {
01018 JacobiSVD<LinearMatrixType> svd(linear(), ComputeFullU | ComputeFullV);
01019
01020 Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant();
01021 VectorType sv(svd.singularValues());
01022 sv.coeffRef(0) *= x;
01023 if(scaling) scaling->lazyAssign(svd.matrixV() * sv.asDiagonal() * svd.matrixV().adjoint());
01024 if(rotation)
01025 {
01026 LinearMatrixType m(svd.matrixU());
01027 m.col(0) /= x;
01028 rotation->lazyAssign(m * svd.matrixV().adjoint());
01029 }
01030 }
01031
01043 template<typename Scalar, int Dim, int Mode, int Options>
01044 template<typename ScalingMatrixType, typename RotationMatrixType>
01045 void Transform<Scalar,Dim,Mode,Options>::computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const
01046 {
01047 JacobiSVD<LinearMatrixType> svd(linear(), ComputeFullU | ComputeFullV);
01048
01049 Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant();
01050 VectorType sv(svd.singularValues());
01051 sv.coeffRef(0) *= x;
01052 if(scaling) scaling->lazyAssign(svd.matrixU() * sv.asDiagonal() * svd.matrixU().adjoint());
01053 if(rotation)
01054 {
01055 LinearMatrixType m(svd.matrixU());
01056 m.col(0) /= x;
01057 rotation->lazyAssign(m * svd.matrixV().adjoint());
01058 }
01059 }
01060
01064 template<typename Scalar, int Dim, int Mode, int Options>
01065 template<typename PositionDerived, typename OrientationType, typename ScaleDerived>
01066 Transform<Scalar,Dim,Mode,Options>&
01067 Transform<Scalar,Dim,Mode,Options>::fromPositionOrientationScale(const MatrixBase<PositionDerived> &position,
01068 const OrientationType& orientation, const MatrixBase<ScaleDerived> &scale)
01069 {
01070 linear() = internal::toRotationMatrix<Scalar,Dim>(orientation);
01071 linear() *= scale.asDiagonal();
01072 translation() = position;
01073 makeAffine();
01074 return *this;
01075 }
01076
01077 namespace internal {
01078
01079 template<int Mode>
01080 struct transform_make_affine
01081 {
01082 template<typename MatrixType>
01083 static void run(MatrixType &mat)
01084 {
01085 static const int Dim = MatrixType::ColsAtCompileTime-1;
01086 mat.template block<1,Dim>(Dim,0).setZero();
01087 mat.coeffRef(Dim,Dim) = typename MatrixType::Scalar(1);
01088 }
01089 };
01090
01091 template<>
01092 struct transform_make_affine<AffineCompact>
01093 {
01094 template<typename MatrixType> static void run(MatrixType &) { }
01095 };
01096
01097
01098 template<typename TransformType, int Mode=TransformType::Mode>
01099 struct projective_transform_inverse
01100 {
01101 static inline void run(const TransformType&, TransformType&)
01102 {}
01103 };
01104
01105 template<typename TransformType>
01106 struct projective_transform_inverse<TransformType, Projective>
01107 {
01108 static inline void run(const TransformType& m, TransformType& res)
01109 {
01110 res.matrix() = m.matrix().inverse();
01111 }
01112 };
01113
01114 }
01115
01116
01137 template<typename Scalar, int Dim, int Mode, int Options>
01138 Transform<Scalar,Dim,Mode,Options>
01139 Transform<Scalar,Dim,Mode,Options>::inverse(TransformTraits hint) const
01140 {
01141 Transform res;
01142 if (hint == Projective)
01143 {
01144 internal::projective_transform_inverse<Transform>::run(*this, res);
01145 }
01146 else
01147 {
01148 if (hint == Isometry)
01149 {
01150 res.matrix().template topLeftCorner<Dim,Dim>() = linear().transpose();
01151 }
01152 else if(hint&Affine)
01153 {
01154 res.matrix().template topLeftCorner<Dim,Dim>() = linear().inverse();
01155 }
01156 else
01157 {
01158 eigen_assert(false && "Invalid transform traits in Transform::Inverse");
01159 }
01160
01161 res.matrix().template topRightCorner<Dim,1>()
01162 = - res.matrix().template topLeftCorner<Dim,Dim>() * translation();
01163 res.makeAffine();
01164 }
01165 return res;
01166 }
01167
01168 namespace internal {
01169
01170
01171
01172
01173
01174 template<typename TransformType> struct transform_take_affine_part {
01175 typedef typename TransformType::MatrixType MatrixType;
01176 typedef typename TransformType::AffinePart AffinePart;
01177 typedef typename TransformType::ConstAffinePart ConstAffinePart;
01178 static inline AffinePart run(MatrixType& m)
01179 { return m.template block<TransformType::Dim,TransformType::HDim>(0,0); }
01180 static inline ConstAffinePart run(const MatrixType& m)
01181 { return m.template block<TransformType::Dim,TransformType::HDim>(0,0); }
01182 };
01183
01184 template<typename Scalar, int Dim, int Options>
01185 struct transform_take_affine_part<Transform<Scalar,Dim,AffineCompact, Options> > {
01186 typedef typename Transform<Scalar,Dim,AffineCompact,Options>::MatrixType MatrixType;
01187 static inline MatrixType& run(MatrixType& m) { return m; }
01188 static inline const MatrixType& run(const MatrixType& m) { return m; }
01189 };
01190
01191
01192
01193
01194
01195 template<typename Other, int Mode, int Options, int Dim, int HDim>
01196 struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, Dim,Dim>
01197 {
01198 static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other)
01199 {
01200 transform->linear() = other;
01201 transform->translation().setZero();
01202 transform->makeAffine();
01203 }
01204 };
01205
01206 template<typename Other, int Mode, int Options, int Dim, int HDim>
01207 struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, Dim,HDim>
01208 {
01209 static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other)
01210 {
01211 transform->affine() = other;
01212 transform->makeAffine();
01213 }
01214 };
01215
01216 template<typename Other, int Mode, int Options, int Dim, int HDim>
01217 struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, HDim,HDim>
01218 {
01219 static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other)
01220 { transform->matrix() = other; }
01221 };
01222
01223 template<typename Other, int Options, int Dim, int HDim>
01224 struct transform_construct_from_matrix<Other, AffineCompact,Options,Dim,HDim, HDim,HDim>
01225 {
01226 static inline void run(Transform<typename Other::Scalar,Dim,AffineCompact,Options> *transform, const Other& other)
01227 { transform->matrix() = other.template block<Dim,HDim>(0,0); }
01228 };
01229
01230
01231
01232
01233
01234 template<int LhsMode,int RhsMode>
01235 struct transform_product_result
01236 {
01237 enum
01238 {
01239 Mode =
01240 (LhsMode == (int)Projective || RhsMode == (int)Projective ) ? Projective :
01241 (LhsMode == (int)Affine || RhsMode == (int)Affine ) ? Affine :
01242 (LhsMode == (int)AffineCompact || RhsMode == (int)AffineCompact ) ? AffineCompact :
01243 (LhsMode == (int)Isometry || RhsMode == (int)Isometry ) ? Isometry : Projective
01244 };
01245 };
01246
01247 template< typename TransformType, typename MatrixType >
01248 struct transform_right_product_impl< TransformType, MatrixType, 0 >
01249 {
01250 typedef typename MatrixType::PlainObject ResultType;
01251
01252 static EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other)
01253 {
01254 return T.matrix() * other;
01255 }
01256 };
01257
01258 template< typename TransformType, typename MatrixType >
01259 struct transform_right_product_impl< TransformType, MatrixType, 1 >
01260 {
01261 enum {
01262 Dim = TransformType::Dim,
01263 HDim = TransformType::HDim,
01264 OtherRows = MatrixType::RowsAtCompileTime,
01265 OtherCols = MatrixType::ColsAtCompileTime
01266 };
01267
01268 typedef typename MatrixType::PlainObject ResultType;
01269
01270 static EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other)
01271 {
01272 EIGEN_STATIC_ASSERT(OtherRows==HDim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);
01273
01274 typedef Block<ResultType, Dim, OtherCols, int(MatrixType::RowsAtCompileTime)==Dim> TopLeftLhs;
01275
01276 ResultType res(other.rows(),other.cols());
01277 TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() = T.affine() * other;
01278 res.row(OtherRows-1) = other.row(OtherRows-1);
01279
01280 return res;
01281 }
01282 };
01283
01284 template< typename TransformType, typename MatrixType >
01285 struct transform_right_product_impl< TransformType, MatrixType, 2 >
01286 {
01287 enum {
01288 Dim = TransformType::Dim,
01289 HDim = TransformType::HDim,
01290 OtherRows = MatrixType::RowsAtCompileTime,
01291 OtherCols = MatrixType::ColsAtCompileTime
01292 };
01293
01294 typedef typename MatrixType::PlainObject ResultType;
01295
01296 static EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other)
01297 {
01298 EIGEN_STATIC_ASSERT(OtherRows==Dim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);
01299
01300 typedef Block<ResultType, Dim, OtherCols, true> TopLeftLhs;
01301 ResultType res(Replicate<typename TransformType::ConstTranslationPart, 1, OtherCols>(T.translation(),1,other.cols()));
01302 TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() += T.linear() * other;
01303
01304 return res;
01305 }
01306 };
01307
01308
01309
01310
01311
01312
01313 template<typename Other,int Mode, int Options, int Dim, int HDim>
01314 struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, HDim,HDim>
01315 {
01316 typedef Transform<typename Other::Scalar,Dim,Mode,Options> TransformType;
01317 typedef typename TransformType::MatrixType MatrixType;
01318 typedef Transform<typename Other::Scalar,Dim,Projective,Options> ResultType;
01319 static ResultType run(const Other& other,const TransformType& tr)
01320 { return ResultType(other * tr.matrix()); }
01321 };
01322
01323
01324 template<typename Other, int Options, int Dim, int HDim>
01325 struct transform_left_product_impl<Other,AffineCompact,Options,Dim,HDim, HDim,HDim>
01326 {
01327 typedef Transform<typename Other::Scalar,Dim,AffineCompact,Options> TransformType;
01328 typedef typename TransformType::MatrixType MatrixType;
01329 typedef Transform<typename Other::Scalar,Dim,Projective,Options> ResultType;
01330 static ResultType run(const Other& other,const TransformType& tr)
01331 {
01332 ResultType res;
01333 res.matrix().noalias() = other.template block<HDim,Dim>(0,0) * tr.matrix();
01334 res.matrix().col(Dim) += other.col(Dim);
01335 return res;
01336 }
01337 };
01338
01339
01340 template<typename Other,int Mode, int Options, int Dim, int HDim>
01341 struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, Dim,HDim>
01342 {
01343 typedef Transform<typename Other::Scalar,Dim,Mode,Options> TransformType;
01344 typedef typename TransformType::MatrixType MatrixType;
01345 typedef TransformType ResultType;
01346 static ResultType run(const Other& other,const TransformType& tr)
01347 {
01348 ResultType res;
01349 res.affine().noalias() = other * tr.matrix();
01350 res.matrix().row(Dim) = tr.matrix().row(Dim);
01351 return res;
01352 }
01353 };
01354
01355
01356 template<typename Other, int Options, int Dim, int HDim>
01357 struct transform_left_product_impl<Other,AffineCompact,Options,Dim,HDim, Dim,HDim>
01358 {
01359 typedef Transform<typename Other::Scalar,Dim,AffineCompact,Options> TransformType;
01360 typedef typename TransformType::MatrixType MatrixType;
01361 typedef TransformType ResultType;
01362 static ResultType run(const Other& other,const TransformType& tr)
01363 {
01364 ResultType res;
01365 res.matrix().noalias() = other.template block<Dim,Dim>(0,0) * tr.matrix();
01366 res.translation() += other.col(Dim);
01367 return res;
01368 }
01369 };
01370
01371
01372 template<typename Other,int Mode, int Options, int Dim, int HDim>
01373 struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, Dim,Dim>
01374 {
01375 typedef Transform<typename Other::Scalar,Dim,Mode,Options> TransformType;
01376 typedef typename TransformType::MatrixType MatrixType;
01377 typedef TransformType ResultType;
01378 static ResultType run(const Other& other, const TransformType& tr)
01379 {
01380 TransformType res;
01381 if(Mode!=int(AffineCompact))
01382 res.matrix().row(Dim) = tr.matrix().row(Dim);
01383 res.matrix().template topRows<Dim>().noalias()
01384 = other * tr.matrix().template topRows<Dim>();
01385 return res;
01386 }
01387 };
01388
01389
01390
01391
01392
01393 template<typename Scalar, int Dim, int LhsMode, int LhsOptions, int RhsMode, int RhsOptions>
01394 struct transform_transform_product_impl<Transform<Scalar,Dim,LhsMode,LhsOptions>,Transform<Scalar,Dim,RhsMode,RhsOptions>,false >
01395 {
01396 enum { ResultMode = transform_product_result<LhsMode,RhsMode>::Mode };
01397 typedef Transform<Scalar,Dim,LhsMode,LhsOptions> Lhs;
01398 typedef Transform<Scalar,Dim,RhsMode,RhsOptions> Rhs;
01399 typedef Transform<Scalar,Dim,ResultMode,LhsOptions> ResultType;
01400 static ResultType run(const Lhs& lhs, const Rhs& rhs)
01401 {
01402 ResultType res;
01403 res.linear() = lhs.linear() * rhs.linear();
01404 res.translation() = lhs.linear() * rhs.translation() + lhs.translation();
01405 res.makeAffine();
01406 return res;
01407 }
01408 };
01409
01410 template<typename Scalar, int Dim, int LhsMode, int LhsOptions, int RhsMode, int RhsOptions>
01411 struct transform_transform_product_impl<Transform<Scalar,Dim,LhsMode,LhsOptions>,Transform<Scalar,Dim,RhsMode,RhsOptions>,true >
01412 {
01413 typedef Transform<Scalar,Dim,LhsMode,LhsOptions> Lhs;
01414 typedef Transform<Scalar,Dim,RhsMode,RhsOptions> Rhs;
01415 typedef Transform<Scalar,Dim,Projective> ResultType;
01416 static ResultType run(const Lhs& lhs, const Rhs& rhs)
01417 {
01418 return ResultType( lhs.matrix() * rhs.matrix() );
01419 }
01420 };
01421
01422 template<typename Scalar, int Dim, int LhsOptions, int RhsOptions>
01423 struct transform_transform_product_impl<Transform<Scalar,Dim,AffineCompact,LhsOptions>,Transform<Scalar,Dim,Projective,RhsOptions>,true >
01424 {
01425 typedef Transform<Scalar,Dim,AffineCompact,LhsOptions> Lhs;
01426 typedef Transform<Scalar,Dim,Projective,RhsOptions> Rhs;
01427 typedef Transform<Scalar,Dim,Projective> ResultType;
01428 static ResultType run(const Lhs& lhs, const Rhs& rhs)
01429 {
01430 ResultType res;
01431 res.matrix().template topRows<Dim>() = lhs.matrix() * rhs.matrix();
01432 res.matrix().row(Dim) = rhs.matrix().row(Dim);
01433 return res;
01434 }
01435 };
01436
01437 template<typename Scalar, int Dim, int LhsOptions, int RhsOptions>
01438 struct transform_transform_product_impl<Transform<Scalar,Dim,Projective,LhsOptions>,Transform<Scalar,Dim,AffineCompact,RhsOptions>,true >
01439 {
01440 typedef Transform<Scalar,Dim,Projective,LhsOptions> Lhs;
01441 typedef Transform<Scalar,Dim,AffineCompact,RhsOptions> Rhs;
01442 typedef Transform<Scalar,Dim,Projective> ResultType;
01443 static ResultType run(const Lhs& lhs, const Rhs& rhs)
01444 {
01445 ResultType res(lhs.matrix().template leftCols<Dim>() * rhs.matrix());
01446 res.matrix().col(Dim) += lhs.matrix().col(Dim);
01447 return res;
01448 }
01449 };
01450
01451 }
01452
01453 }
01454
01455 #endif // EIGEN_TRANSFORM_H