00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef EIGEN_TRANSFORM_H
00028 #define EIGEN_TRANSFORM_H
00029
00030 namespace internal {
00031
00032 template<typename Transform>
00033 struct transform_traits
00034 {
00035 enum
00036 {
00037 Dim = Transform::Dim,
00038 HDim = Transform::HDim,
00039 Mode = Transform::Mode,
00040 IsProjective = (Mode==Projective)
00041 };
00042 };
00043
00044 template< typename TransformType,
00045 typename MatrixType,
00046 int Case = transform_traits<TransformType>::IsProjective ? 0
00047 : int(MatrixType::RowsAtCompileTime) == int(transform_traits<TransformType>::HDim) ? 1
00048 : 2>
00049 struct transform_right_product_impl;
00050
00051 template< typename Other,
00052 int Mode,
00053 int Options,
00054 int Dim,
00055 int HDim,
00056 int OtherRows=Other::RowsAtCompileTime,
00057 int OtherCols=Other::ColsAtCompileTime>
00058 struct transform_left_product_impl;
00059
00060 template< typename Lhs,
00061 typename Rhs,
00062 bool AnyProjective =
00063 transform_traits<Lhs>::IsProjective ||
00064 transform_traits<Lhs>::IsProjective>
00065 struct transform_transform_product_impl;
00066
00067 template< typename Other,
00068 int Mode,
00069 int Options,
00070 int Dim,
00071 int HDim,
00072 int OtherRows=Other::RowsAtCompileTime,
00073 int OtherCols=Other::ColsAtCompileTime>
00074 struct transform_construct_from_matrix;
00075
00076 template<typename TransformType> struct transform_take_affine_part;
00077
00078 }
00079
00188 template<typename _Scalar, int _Dim, int _Mode, int _Options>
00189 class Transform
00190 {
00191 public:
00192 EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_Dim==Dynamic ? Dynamic : (_Dim+1)*(_Dim+1))
00193 enum {
00194 Mode = _Mode,
00195 Options = _Options,
00196 Dim = _Dim,
00197 HDim = _Dim+1,
00198 Rows = int(Mode)==(AffineCompact) ? Dim : HDim
00199 };
00201 typedef _Scalar Scalar;
00202 typedef DenseIndex Index;
00204 typedef typename internal::make_proper_matrix_type<Scalar,Rows,HDim,Options>::type MatrixType;
00206 typedef const MatrixType ConstMatrixType;
00208 typedef Matrix<Scalar,Dim,Dim,Options> LinearMatrixType;
00210 typedef Block<MatrixType,Dim,Dim> LinearPart;
00212 typedef const Block<ConstMatrixType,Dim,Dim> ConstLinearPart;
00214 typedef typename internal::conditional<int(Mode)==int(AffineCompact),
00215 MatrixType&,
00216 Block<MatrixType,Dim,HDim> >::type AffinePart;
00218 typedef typename internal::conditional<int(Mode)==int(AffineCompact),
00219 const MatrixType&,
00220 const Block<const MatrixType,Dim,HDim> >::type ConstAffinePart;
00222 typedef Matrix<Scalar,Dim,1> VectorType;
00224 typedef Block<MatrixType,Dim,1> TranslationPart;
00226 typedef const Block<ConstMatrixType,Dim,1> ConstTranslationPart;
00228 typedef Translation<Scalar,Dim> TranslationType;
00229
00230
00231 enum { TransformTimeDiagonalMode = ((Mode==int(Isometry))?Affine:int(Mode)) };
00233 typedef Transform<Scalar,Dim,TransformTimeDiagonalMode> TransformTimeDiagonalReturnType;
00234
00235 protected:
00236
00237 MatrixType m_matrix;
00238
00239 public:
00240
00243 inline Transform()
00244 {
00245 check_template_params();
00246 if (int(Mode)==Affine)
00247 makeAffine();
00248 }
00249
00250 inline Transform(const Transform& other)
00251 {
00252 check_template_params();
00253 m_matrix = other.m_matrix;
00254 }
00255
00256 inline explicit Transform(const TranslationType& t)
00257 {
00258 check_template_params();
00259 *this = t;
00260 }
00261 inline explicit Transform(const UniformScaling<Scalar>& s)
00262 {
00263 check_template_params();
00264 *this = s;
00265 }
00266 template<typename Derived>
00267 inline explicit Transform(const RotationBase<Derived, Dim>& r)
00268 {
00269 check_template_params();
00270 *this = r;
00271 }
00272
00273 inline Transform& operator=(const Transform& other)
00274 { m_matrix = other.m_matrix; return *this; }
00275
00276 typedef internal::transform_take_affine_part<Transform> take_affine_part;
00277
00279 template<typename OtherDerived>
00280 inline explicit Transform(const EigenBase<OtherDerived>& other)
00281 {
00282 check_template_params();
00283 internal::transform_construct_from_matrix<OtherDerived,Mode,Options,Dim,HDim>::run(this, other.derived());
00284 }
00285
00287 template<typename OtherDerived>
00288 inline Transform& operator=(const EigenBase<OtherDerived>& other)
00289 {
00290 internal::transform_construct_from_matrix<OtherDerived,Mode,Options,Dim,HDim>::run(this, other.derived());
00291 return *this;
00292 }
00293
00294 template<int OtherOptions>
00295 inline Transform(const Transform<Scalar,Dim,Mode,OtherOptions>& other)
00296 {
00297 check_template_params();
00298
00299 m_matrix = other.matrix();
00300 }
00301
00302 template<int OtherMode,int OtherOptions>
00303 inline Transform(const Transform<Scalar,Dim,OtherMode,OtherOptions>& other)
00304 {
00305 check_template_params();
00306
00307
00308 EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(OtherMode==int(Projective), Mode==int(Projective)),
00309 YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION)
00310
00311
00312
00313 EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(OtherMode==int(Affine)||OtherMode==int(AffineCompact), Mode!=int(Isometry)),
00314 YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION)
00315
00316 enum { ModeIsAffineCompact = Mode == int(AffineCompact),
00317 OtherModeIsAffineCompact = OtherMode == int(AffineCompact)
00318 };
00319
00320 if(ModeIsAffineCompact == OtherModeIsAffineCompact)
00321 {
00322
00323
00324
00325 m_matrix.template block<Dim,Dim+1>(0,0) = other.matrix().template block<Dim,Dim+1>(0,0);
00326 makeAffine();
00327 }
00328 else if(OtherModeIsAffineCompact)
00329 {
00330 typedef typename Transform<Scalar,Dim,OtherMode,OtherOptions>::MatrixType OtherMatrixType;
00331 internal::transform_construct_from_matrix<OtherMatrixType,Mode,Options,Dim,HDim>::run(this, other.matrix());
00332 }
00333 else
00334 {
00335
00336
00337
00338 linear() = other.linear();
00339 translation() = other.translation();
00340 }
00341 }
00342
00343 template<typename OtherDerived>
00344 Transform(const ReturnByValue<OtherDerived>& other)
00345 {
00346 check_template_params();
00347 other.evalTo(*this);
00348 }
00349
00350 template<typename OtherDerived>
00351 Transform& operator=(const ReturnByValue<OtherDerived>& other)
00352 {
00353 other.evalTo(*this);
00354 return *this;
00355 }
00356
00357 #ifdef EIGEN_QT_SUPPORT
00358 inline Transform(const QMatrix& other);
00359 inline Transform& operator=(const QMatrix& other);
00360 inline QMatrix toQMatrix(void) const;
00361 inline Transform(const QTransform& other);
00362 inline Transform& operator=(const QTransform& other);
00363 inline QTransform toQTransform(void) const;
00364 #endif
00365
00368 inline Scalar operator() (Index row, Index col) const { return m_matrix(row,col); }
00371 inline Scalar& operator() (Index row, Index col) { return m_matrix(row,col); }
00372
00374 inline const MatrixType& matrix() const { return m_matrix; }
00376 inline MatrixType& matrix() { return m_matrix; }
00377
00379 inline ConstLinearPart linear() const { return m_matrix.template block<Dim,Dim>(0,0); }
00381 inline LinearPart linear() { return m_matrix.template block<Dim,Dim>(0,0); }
00382
00384 inline ConstAffinePart affine() const { return take_affine_part::run(m_matrix); }
00386 inline AffinePart affine() { return take_affine_part::run(m_matrix); }
00387
00389 inline ConstTranslationPart translation() const { return m_matrix.template block<Dim,1>(0,Dim); }
00391 inline TranslationPart translation() { return m_matrix.template block<Dim,1>(0,Dim); }
00392
00404
00405 template<typename OtherDerived>
00406 EIGEN_STRONG_INLINE const typename internal::transform_right_product_impl<Transform, OtherDerived>::ResultType
00407 operator * (const EigenBase<OtherDerived> &other) const
00408 { return internal::transform_right_product_impl<Transform, OtherDerived>::run(*this,other.derived()); }
00409
00417 template<typename OtherDerived> friend
00418 inline const typename internal::transform_left_product_impl<OtherDerived,Mode,Options,_Dim,_Dim+1>::ResultType
00419 operator * (const EigenBase<OtherDerived> &a, const Transform &b)
00420 { return internal::transform_left_product_impl<OtherDerived,Mode,Options,Dim,HDim>::run(a.derived(),b); }
00421
00428 template<typename DiagonalDerived>
00429 inline const TransformTimeDiagonalReturnType
00430 operator * (const DiagonalBase<DiagonalDerived> &b) const
00431 {
00432 TransformTimeDiagonalReturnType res(*this);
00433 res.linear() *= b;
00434 return res;
00435 }
00436
00443 template<typename DiagonalDerived>
00444 friend inline TransformTimeDiagonalReturnType
00445 operator * (const DiagonalBase<DiagonalDerived> &a, const Transform &b)
00446 {
00447 TransformTimeDiagonalReturnType res;
00448 res.linear().noalias() = a*b.linear();
00449 res.translation().noalias() = a*b.translation();
00450 if (Mode!=int(AffineCompact))
00451 res.matrix().row(Dim) = b.matrix().row(Dim);
00452 return res;
00453 }
00454
00455 template<typename OtherDerived>
00456 inline Transform& operator*=(const EigenBase<OtherDerived>& other) { return *this = *this * other; }
00457
00459 inline const Transform operator * (const Transform& other) const
00460 {
00461 return internal::transform_transform_product_impl<Transform,Transform>::run(*this,other);
00462 }
00463
00465 template<int OtherMode,int OtherOptions>
00466 inline const typename internal::transform_transform_product_impl<
00467 Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> >::ResultType
00468 operator * (const Transform<Scalar,Dim,OtherMode,OtherOptions>& other) const
00469 {
00470 return internal::transform_transform_product_impl<Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> >::run(*this,other);
00471 }
00472
00474 void setIdentity() { m_matrix.setIdentity(); }
00475
00480 static const Transform Identity()
00481 {
00482 return Transform(MatrixType::Identity());
00483 }
00484
00485 template<typename OtherDerived>
00486 inline Transform& scale(const MatrixBase<OtherDerived> &other);
00487
00488 template<typename OtherDerived>
00489 inline Transform& prescale(const MatrixBase<OtherDerived> &other);
00490
00491 inline Transform& scale(Scalar s);
00492 inline Transform& prescale(Scalar s);
00493
00494 template<typename OtherDerived>
00495 inline Transform& translate(const MatrixBase<OtherDerived> &other);
00496
00497 template<typename OtherDerived>
00498 inline Transform& pretranslate(const MatrixBase<OtherDerived> &other);
00499
00500 template<typename RotationType>
00501 inline Transform& rotate(const RotationType& rotation);
00502
00503 template<typename RotationType>
00504 inline Transform& prerotate(const RotationType& rotation);
00505
00506 Transform& shear(Scalar sx, Scalar sy);
00507 Transform& preshear(Scalar sx, Scalar sy);
00508
00509 inline Transform& operator=(const TranslationType& t);
00510 inline Transform& operator*=(const TranslationType& t) { return translate(t.vector()); }
00511 inline Transform operator*(const TranslationType& t) const;
00512
00513 inline Transform& operator=(const UniformScaling<Scalar>& t);
00514 inline Transform& operator*=(const UniformScaling<Scalar>& s) { return scale(s.factor()); }
00515 inline Transform operator*(const UniformScaling<Scalar>& s) const;
00516
00517 inline Transform& operator*=(const DiagonalMatrix<Scalar,Dim>& s) { linear() *= s; return *this; }
00518
00519 template<typename Derived>
00520 inline Transform& operator=(const RotationBase<Derived,Dim>& r);
00521 template<typename Derived>
00522 inline Transform& operator*=(const RotationBase<Derived,Dim>& r) { return rotate(r.toRotationMatrix()); }
00523 template<typename Derived>
00524 inline Transform operator*(const RotationBase<Derived,Dim>& r) const;
00525
00526 const LinearMatrixType rotation() const;
00527 template<typename RotationMatrixType, typename ScalingMatrixType>
00528 void computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const;
00529 template<typename ScalingMatrixType, typename RotationMatrixType>
00530 void computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const;
00531
00532 template<typename PositionDerived, typename OrientationType, typename ScaleDerived>
00533 Transform& fromPositionOrientationScale(const MatrixBase<PositionDerived> &position,
00534 const OrientationType& orientation, const MatrixBase<ScaleDerived> &scale);
00535
00536 inline Transform inverse(TransformTraits traits = (TransformTraits)Mode) const;
00537
00539 const Scalar* data() const { return m_matrix.data(); }
00541 Scalar* data() { return m_matrix.data(); }
00542
00548 template<typename NewScalarType>
00549 inline typename internal::cast_return_type<Transform,Transform<NewScalarType,Dim,Mode,Options> >::type cast() const
00550 { return typename internal::cast_return_type<Transform,Transform<NewScalarType,Dim,Mode,Options> >::type(*this); }
00551
00553 template<typename OtherScalarType>
00554 inline explicit Transform(const Transform<OtherScalarType,Dim,Mode,Options>& other)
00555 {
00556 check_template_params();
00557 m_matrix = other.matrix().template cast<Scalar>();
00558 }
00559
00564 bool isApprox(const Transform& other, typename NumTraits<Scalar>::Real prec = NumTraits<Scalar>::dummy_precision()) const
00565 { return m_matrix.isApprox(other.m_matrix, prec); }
00566
00569 void makeAffine()
00570 {
00571 if(int(Mode)!=int(AffineCompact))
00572 {
00573 matrix().template block<1,Dim>(Dim,0).setZero();
00574 matrix().coeffRef(Dim,Dim) = 1;
00575 }
00576 }
00577
00582 inline Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,Dim> linearExt()
00583 { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,Dim>(0,0); }
00588 inline const Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,Dim> linearExt() const
00589 { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,Dim>(0,0); }
00590
00595 inline Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,1> translationExt()
00596 { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,1>(0,Dim); }
00601 inline const Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,1> translationExt() const
00602 { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,1>(0,Dim); }
00603
00604
00605 #ifdef EIGEN_TRANSFORM_PLUGIN
00606 #include EIGEN_TRANSFORM_PLUGIN
00607 #endif
00608
00609 protected:
00610 #ifndef EIGEN_PARSED_BY_DOXYGEN
00611 EIGEN_STRONG_INLINE static void check_template_params()
00612 {
00613 EIGEN_STATIC_ASSERT((Options & (DontAlign|RowMajor)) == Options, INVALID_MATRIX_TEMPLATE_PARAMETERS)
00614 }
00615 #endif
00616
00617 };
00618
00620 typedef Transform<float,2,Isometry> Isometry2f;
00622 typedef Transform<float,3,Isometry> Isometry3f;
00624 typedef Transform<double,2,Isometry> Isometry2d;
00626 typedef Transform<double,3,Isometry> Isometry3d;
00627
00629 typedef Transform<float,2,Affine> Affine2f;
00631 typedef Transform<float,3,Affine> Affine3f;
00633 typedef Transform<double,2,Affine> Affine2d;
00635 typedef Transform<double,3,Affine> Affine3d;
00636
00638 typedef Transform<float,2,AffineCompact> AffineCompact2f;
00640 typedef Transform<float,3,AffineCompact> AffineCompact3f;
00642 typedef Transform<double,2,AffineCompact> AffineCompact2d;
00644 typedef Transform<double,3,AffineCompact> AffineCompact3d;
00645
00647 typedef Transform<float,2,Projective> Projective2f;
00649 typedef Transform<float,3,Projective> Projective3f;
00651 typedef Transform<double,2,Projective> Projective2d;
00653 typedef Transform<double,3,Projective> Projective3d;
00654
00655
00656
00657
00658
00659 #ifdef EIGEN_QT_SUPPORT
00660
00664 template<typename Scalar, int Dim, int Mode,int Options>
00665 Transform<Scalar,Dim,Mode,Options>::Transform(const QMatrix& other)
00666 {
00667 check_template_params();
00668 *this = other;
00669 }
00670
00675 template<typename Scalar, int Dim, int Mode,int Options>
00676 Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const QMatrix& other)
00677 {
00678 EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00679 m_matrix << other.m11(), other.m21(), other.dx(),
00680 other.m12(), other.m22(), other.dy(),
00681 0, 0, 1;
00682 return *this;
00683 }
00684
00691 template<typename Scalar, int Dim, int Mode, int Options>
00692 QMatrix Transform<Scalar,Dim,Mode,Options>::toQMatrix(void) const
00693 {
00694 check_template_params();
00695 EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00696 return QMatrix(m_matrix.coeff(0,0), m_matrix.coeff(1,0),
00697 m_matrix.coeff(0,1), m_matrix.coeff(1,1),
00698 m_matrix.coeff(0,2), m_matrix.coeff(1,2));
00699 }
00700
00705 template<typename Scalar, int Dim, int Mode,int Options>
00706 Transform<Scalar,Dim,Mode,Options>::Transform(const QTransform& other)
00707 {
00708 check_template_params();
00709 *this = other;
00710 }
00711
00716 template<typename Scalar, int Dim, int Mode, int Options>
00717 Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const QTransform& other)
00718 {
00719 check_template_params();
00720 EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00721 if (Mode == int(AffineCompact))
00722 m_matrix << other.m11(), other.m21(), other.dx(),
00723 other.m12(), other.m22(), other.dy();
00724 else
00725 m_matrix << other.m11(), other.m21(), other.dx(),
00726 other.m12(), other.m22(), other.dy(),
00727 other.m13(), other.m23(), other.m33();
00728 return *this;
00729 }
00730
00735 template<typename Scalar, int Dim, int Mode, int Options>
00736 QTransform Transform<Scalar,Dim,Mode,Options>::toQTransform(void) const
00737 {
00738 EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00739 if (Mode == int(AffineCompact))
00740 return QTransform(m_matrix.coeff(0,0), m_matrix.coeff(1,0),
00741 m_matrix.coeff(0,1), m_matrix.coeff(1,1),
00742 m_matrix.coeff(0,2), m_matrix.coeff(1,2));
00743 else
00744 return QTransform(m_matrix.coeff(0,0), m_matrix.coeff(1,0), m_matrix.coeff(2,0),
00745 m_matrix.coeff(0,1), m_matrix.coeff(1,1), m_matrix.coeff(2,1),
00746 m_matrix.coeff(0,2), m_matrix.coeff(1,2), m_matrix.coeff(2,2));
00747 }
00748 #endif
00749
00750
00751
00752
00753
00758 template<typename Scalar, int Dim, int Mode, int Options>
00759 template<typename OtherDerived>
00760 Transform<Scalar,Dim,Mode,Options>&
00761 Transform<Scalar,Dim,Mode,Options>::scale(const MatrixBase<OtherDerived> &other)
00762 {
00763 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
00764 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
00765 linearExt().noalias() = (linearExt() * other.asDiagonal());
00766 return *this;
00767 }
00768
00773 template<typename Scalar, int Dim, int Mode, int Options>
00774 inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::scale(Scalar s)
00775 {
00776 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
00777 linearExt() *= s;
00778 return *this;
00779 }
00780
00785 template<typename Scalar, int Dim, int Mode, int Options>
00786 template<typename OtherDerived>
00787 Transform<Scalar,Dim,Mode,Options>&
00788 Transform<Scalar,Dim,Mode,Options>::prescale(const MatrixBase<OtherDerived> &other)
00789 {
00790 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
00791 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
00792 m_matrix.template block<Dim,HDim>(0,0).noalias() = (other.asDiagonal() * m_matrix.template block<Dim,HDim>(0,0));
00793 return *this;
00794 }
00795
00800 template<typename Scalar, int Dim, int Mode, int Options>
00801 inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::prescale(Scalar s)
00802 {
00803 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
00804 m_matrix.template topRows<Dim>() *= s;
00805 return *this;
00806 }
00807
00812 template<typename Scalar, int Dim, int Mode, int Options>
00813 template<typename OtherDerived>
00814 Transform<Scalar,Dim,Mode,Options>&
00815 Transform<Scalar,Dim,Mode,Options>::translate(const MatrixBase<OtherDerived> &other)
00816 {
00817 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
00818 translationExt() += linearExt() * other;
00819 return *this;
00820 }
00821
00826 template<typename Scalar, int Dim, int Mode, int Options>
00827 template<typename OtherDerived>
00828 Transform<Scalar,Dim,Mode,Options>&
00829 Transform<Scalar,Dim,Mode,Options>::pretranslate(const MatrixBase<OtherDerived> &other)
00830 {
00831 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
00832 if(int(Mode)==int(Projective))
00833 affine() += other * m_matrix.row(Dim);
00834 else
00835 translation() += other;
00836 return *this;
00837 }
00838
00856 template<typename Scalar, int Dim, int Mode, int Options>
00857 template<typename RotationType>
00858 Transform<Scalar,Dim,Mode,Options>&
00859 Transform<Scalar,Dim,Mode,Options>::rotate(const RotationType& rotation)
00860 {
00861 linearExt() *= internal::toRotationMatrix<Scalar,Dim>(rotation);
00862 return *this;
00863 }
00864
00872 template<typename Scalar, int Dim, int Mode, int Options>
00873 template<typename RotationType>
00874 Transform<Scalar,Dim,Mode,Options>&
00875 Transform<Scalar,Dim,Mode,Options>::prerotate(const RotationType& rotation)
00876 {
00877 m_matrix.template block<Dim,HDim>(0,0) = internal::toRotationMatrix<Scalar,Dim>(rotation)
00878 * m_matrix.template block<Dim,HDim>(0,0);
00879 return *this;
00880 }
00881
00887 template<typename Scalar, int Dim, int Mode, int Options>
00888 Transform<Scalar,Dim,Mode,Options>&
00889 Transform<Scalar,Dim,Mode,Options>::shear(Scalar sx, Scalar sy)
00890 {
00891 EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00892 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
00893 VectorType tmp = linear().col(0)*sy + linear().col(1);
00894 linear() << linear().col(0) + linear().col(1)*sx, tmp;
00895 return *this;
00896 }
00897
00903 template<typename Scalar, int Dim, int Mode, int Options>
00904 Transform<Scalar,Dim,Mode,Options>&
00905 Transform<Scalar,Dim,Mode,Options>::preshear(Scalar sx, Scalar sy)
00906 {
00907 EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00908 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
00909 m_matrix.template block<Dim,HDim>(0,0) = LinearMatrixType(1, sx, sy, 1) * m_matrix.template block<Dim,HDim>(0,0);
00910 return *this;
00911 }
00912
00913
00914
00915
00916
00917 template<typename Scalar, int Dim, int Mode, int Options>
00918 inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const TranslationType& t)
00919 {
00920 linear().setIdentity();
00921 translation() = t.vector();
00922 makeAffine();
00923 return *this;
00924 }
00925
00926 template<typename Scalar, int Dim, int Mode, int Options>
00927 inline Transform<Scalar,Dim,Mode,Options> Transform<Scalar,Dim,Mode,Options>::operator*(const TranslationType& t) const
00928 {
00929 Transform res = *this;
00930 res.translate(t.vector());
00931 return res;
00932 }
00933
00934 template<typename Scalar, int Dim, int Mode, int Options>
00935 inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const UniformScaling<Scalar>& s)
00936 {
00937 m_matrix.setZero();
00938 linear().diagonal().fill(s.factor());
00939 makeAffine();
00940 return *this;
00941 }
00942
00943 template<typename Scalar, int Dim, int Mode, int Options>
00944 inline Transform<Scalar,Dim,Mode,Options> Transform<Scalar,Dim,Mode,Options>::operator*(const UniformScaling<Scalar>& s) const
00945 {
00946 Transform res = *this;
00947 res.scale(s.factor());
00948 return res;
00949 }
00950
00951 template<typename Scalar, int Dim, int Mode, int Options>
00952 template<typename Derived>
00953 inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const RotationBase<Derived,Dim>& r)
00954 {
00955 linear() = internal::toRotationMatrix<Scalar,Dim>(r);
00956 translation().setZero();
00957 makeAffine();
00958 return *this;
00959 }
00960
00961 template<typename Scalar, int Dim, int Mode, int Options>
00962 template<typename Derived>
00963 inline Transform<Scalar,Dim,Mode,Options> Transform<Scalar,Dim,Mode,Options>::operator*(const RotationBase<Derived,Dim>& r) const
00964 {
00965 Transform res = *this;
00966 res.rotate(r.derived());
00967 return res;
00968 }
00969
00970
00971
00972
00973
00981 template<typename Scalar, int Dim, int Mode, int Options>
00982 const typename Transform<Scalar,Dim,Mode,Options>::LinearMatrixType
00983 Transform<Scalar,Dim,Mode,Options>::rotation() const
00984 {
00985 LinearMatrixType result;
00986 computeRotationScaling(&result, (LinearMatrixType*)0);
00987 return result;
00988 }
00989
00990
01002 template<typename Scalar, int Dim, int Mode, int Options>
01003 template<typename RotationMatrixType, typename ScalingMatrixType>
01004 void Transform<Scalar,Dim,Mode,Options>::computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const
01005 {
01006 JacobiSVD<LinearMatrixType> svd(linear(), ComputeFullU | ComputeFullV);
01007
01008 Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant();
01009 VectorType sv(svd.singularValues());
01010 sv.coeffRef(0) *= x;
01011 if(scaling) scaling->lazyAssign(svd.matrixV() * sv.asDiagonal() * svd.matrixV().adjoint());
01012 if(rotation)
01013 {
01014 LinearMatrixType m(svd.matrixU());
01015 m.col(0) /= x;
01016 rotation->lazyAssign(m * svd.matrixV().adjoint());
01017 }
01018 }
01019
01031 template<typename Scalar, int Dim, int Mode, int Options>
01032 template<typename ScalingMatrixType, typename RotationMatrixType>
01033 void Transform<Scalar,Dim,Mode,Options>::computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const
01034 {
01035 JacobiSVD<LinearMatrixType> svd(linear(), ComputeFullU | ComputeFullV);
01036
01037 Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant();
01038 VectorType sv(svd.singularValues());
01039 sv.coeffRef(0) *= x;
01040 if(scaling) scaling->lazyAssign(svd.matrixU() * sv.asDiagonal() * svd.matrixU().adjoint());
01041 if(rotation)
01042 {
01043 LinearMatrixType m(svd.matrixU());
01044 m.col(0) /= x;
01045 rotation->lazyAssign(m * svd.matrixV().adjoint());
01046 }
01047 }
01048
01052 template<typename Scalar, int Dim, int Mode, int Options>
01053 template<typename PositionDerived, typename OrientationType, typename ScaleDerived>
01054 Transform<Scalar,Dim,Mode,Options>&
01055 Transform<Scalar,Dim,Mode,Options>::fromPositionOrientationScale(const MatrixBase<PositionDerived> &position,
01056 const OrientationType& orientation, const MatrixBase<ScaleDerived> &scale)
01057 {
01058 linear() = internal::toRotationMatrix<Scalar,Dim>(orientation);
01059 linear() *= scale.asDiagonal();
01060 translation() = position;
01061 makeAffine();
01062 return *this;
01063 }
01064
01065 namespace internal {
01066
01067
01068 template<typename TransformType, int Mode=TransformType::Mode>
01069 struct projective_transform_inverse
01070 {
01071 static inline void run(const TransformType&, TransformType&)
01072 {}
01073 };
01074
01075 template<typename TransformType>
01076 struct projective_transform_inverse<TransformType, Projective>
01077 {
01078 static inline void run(const TransformType& m, TransformType& res)
01079 {
01080 res.matrix() = m.matrix().inverse();
01081 }
01082 };
01083
01084 }
01085
01086
01107 template<typename Scalar, int Dim, int Mode, int Options>
01108 Transform<Scalar,Dim,Mode,Options>
01109 Transform<Scalar,Dim,Mode,Options>::inverse(TransformTraits hint) const
01110 {
01111 Transform res;
01112 if (hint == Projective)
01113 {
01114 internal::projective_transform_inverse<Transform>::run(*this, res);
01115 }
01116 else
01117 {
01118 if (hint == Isometry)
01119 {
01120 res.matrix().template topLeftCorner<Dim,Dim>() = linear().transpose();
01121 }
01122 else if(hint&Affine)
01123 {
01124 res.matrix().template topLeftCorner<Dim,Dim>() = linear().inverse();
01125 }
01126 else
01127 {
01128 eigen_assert(false && "Invalid transform traits in Transform::Inverse");
01129 }
01130
01131 res.matrix().template topRightCorner<Dim,1>()
01132 = - res.matrix().template topLeftCorner<Dim,Dim>() * translation();
01133 res.makeAffine();
01134 }
01135 return res;
01136 }
01137
01138 namespace internal {
01139
01140
01141
01142
01143
01144 template<typename TransformType> struct transform_take_affine_part {
01145 typedef typename TransformType::MatrixType MatrixType;
01146 typedef typename TransformType::AffinePart AffinePart;
01147 typedef typename TransformType::ConstAffinePart ConstAffinePart;
01148 static inline AffinePart run(MatrixType& m)
01149 { return m.template block<TransformType::Dim,TransformType::HDim>(0,0); }
01150 static inline ConstAffinePart run(const MatrixType& m)
01151 { return m.template block<TransformType::Dim,TransformType::HDim>(0,0); }
01152 };
01153
01154 template<typename Scalar, int Dim, int Options>
01155 struct transform_take_affine_part<Transform<Scalar,Dim,AffineCompact, Options> > {
01156 typedef typename Transform<Scalar,Dim,AffineCompact,Options>::MatrixType MatrixType;
01157 static inline MatrixType& run(MatrixType& m) { return m; }
01158 static inline const MatrixType& run(const MatrixType& m) { return m; }
01159 };
01160
01161
01162
01163
01164
01165 template<typename Other, int Mode, int Options, int Dim, int HDim>
01166 struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, Dim,Dim>
01167 {
01168 static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other)
01169 {
01170 transform->linear() = other;
01171 transform->translation().setZero();
01172 transform->makeAffine();
01173 }
01174 };
01175
01176 template<typename Other, int Mode, int Options, int Dim, int HDim>
01177 struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, Dim,HDim>
01178 {
01179 static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other)
01180 {
01181 transform->affine() = other;
01182 transform->makeAffine();
01183 }
01184 };
01185
01186 template<typename Other, int Mode, int Options, int Dim, int HDim>
01187 struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, HDim,HDim>
01188 {
01189 static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other)
01190 { transform->matrix() = other; }
01191 };
01192
01193 template<typename Other, int Options, int Dim, int HDim>
01194 struct transform_construct_from_matrix<Other, AffineCompact,Options,Dim,HDim, HDim,HDim>
01195 {
01196 static inline void run(Transform<typename Other::Scalar,Dim,AffineCompact,Options> *transform, const Other& other)
01197 { transform->matrix() = other.template block<Dim,HDim>(0,0); }
01198 };
01199
01200
01201
01202
01203
01204 template<int LhsMode,int RhsMode>
01205 struct transform_product_result
01206 {
01207 enum
01208 {
01209 Mode =
01210 (LhsMode == (int)Projective || RhsMode == (int)Projective ) ? Projective :
01211 (LhsMode == (int)Affine || RhsMode == (int)Affine ) ? Affine :
01212 (LhsMode == (int)AffineCompact || RhsMode == (int)AffineCompact ) ? AffineCompact :
01213 (LhsMode == (int)Isometry || RhsMode == (int)Isometry ) ? Isometry : Projective
01214 };
01215 };
01216
01217 template< typename TransformType, typename MatrixType >
01218 struct transform_right_product_impl< TransformType, MatrixType, 0 >
01219 {
01220 typedef typename MatrixType::PlainObject ResultType;
01221
01222 EIGEN_STRONG_INLINE static ResultType run(const TransformType& T, const MatrixType& other)
01223 {
01224 return T.matrix() * other;
01225 }
01226 };
01227
01228 template< typename TransformType, typename MatrixType >
01229 struct transform_right_product_impl< TransformType, MatrixType, 1 >
01230 {
01231 enum {
01232 Dim = TransformType::Dim,
01233 HDim = TransformType::HDim,
01234 OtherRows = MatrixType::RowsAtCompileTime,
01235 OtherCols = MatrixType::ColsAtCompileTime
01236 };
01237
01238 typedef typename MatrixType::PlainObject ResultType;
01239
01240 EIGEN_STRONG_INLINE static ResultType run(const TransformType& T, const MatrixType& other)
01241 {
01242 EIGEN_STATIC_ASSERT(OtherRows==HDim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);
01243
01244 typedef Block<ResultType, Dim, OtherCols> TopLeftLhs;
01245
01246 ResultType res(other.rows(),other.cols());
01247 TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() = T.affine() * other;
01248 res.row(OtherRows-1) = other.row(OtherRows-1);
01249
01250 return res;
01251 }
01252 };
01253
01254 template< typename TransformType, typename MatrixType >
01255 struct transform_right_product_impl< TransformType, MatrixType, 2 >
01256 {
01257 enum {
01258 Dim = TransformType::Dim,
01259 HDim = TransformType::HDim,
01260 OtherRows = MatrixType::RowsAtCompileTime,
01261 OtherCols = MatrixType::ColsAtCompileTime
01262 };
01263
01264 typedef typename MatrixType::PlainObject ResultType;
01265
01266 EIGEN_STRONG_INLINE static ResultType run(const TransformType& T, const MatrixType& other)
01267 {
01268 EIGEN_STATIC_ASSERT(OtherRows==Dim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);
01269
01270 typedef Block<ResultType, Dim, OtherCols> TopLeftLhs;
01271
01272 ResultType res(other.rows(),other.cols());
01273 TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() = T.linear() * other;
01274 TopLeftLhs(res, 0, 0, Dim, other.cols()).colwise() += T.translation();
01275
01276 return res;
01277 }
01278 };
01279
01280
01281
01282
01283
01284
01285 template<typename Other,int Mode, int Options, int Dim, int HDim>
01286 struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, HDim,HDim>
01287 {
01288 typedef Transform<typename Other::Scalar,Dim,Mode,Options> TransformType;
01289 typedef typename TransformType::MatrixType MatrixType;
01290 typedef Transform<typename Other::Scalar,Dim,Projective,Options> ResultType;
01291 static ResultType run(const Other& other,const TransformType& tr)
01292 { return ResultType(other * tr.matrix()); }
01293 };
01294
01295
01296 template<typename Other, int Options, int Dim, int HDim>
01297 struct transform_left_product_impl<Other,AffineCompact,Options,Dim,HDim, HDim,HDim>
01298 {
01299 typedef Transform<typename Other::Scalar,Dim,AffineCompact,Options> TransformType;
01300 typedef typename TransformType::MatrixType MatrixType;
01301 typedef Transform<typename Other::Scalar,Dim,Projective,Options> ResultType;
01302 static ResultType run(const Other& other,const TransformType& tr)
01303 {
01304 ResultType res;
01305 res.matrix().noalias() = other.template block<HDim,Dim>(0,0) * tr.matrix();
01306 res.matrix().col(Dim) += other.col(Dim);
01307 return res;
01308 }
01309 };
01310
01311
01312 template<typename Other,int Mode, int Options, int Dim, int HDim>
01313 struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, Dim,HDim>
01314 {
01315 typedef Transform<typename Other::Scalar,Dim,Mode,Options> TransformType;
01316 typedef typename TransformType::MatrixType MatrixType;
01317 typedef TransformType ResultType;
01318 static ResultType run(const Other& other,const TransformType& tr)
01319 {
01320 ResultType res;
01321 res.affine().noalias() = other * tr.matrix();
01322 res.matrix().row(Dim) = tr.matrix().row(Dim);
01323 return res;
01324 }
01325 };
01326
01327
01328 template<typename Other, int Options, int Dim, int HDim>
01329 struct transform_left_product_impl<Other,AffineCompact,Options,Dim,HDim, Dim,HDim>
01330 {
01331 typedef Transform<typename Other::Scalar,Dim,AffineCompact,Options> TransformType;
01332 typedef typename TransformType::MatrixType MatrixType;
01333 typedef TransformType ResultType;
01334 static ResultType run(const Other& other,const TransformType& tr)
01335 {
01336 ResultType res;
01337 res.matrix().noalias() = other.template block<Dim,Dim>(0,0) * tr.matrix();
01338 res.translation() += other.col(Dim);
01339 return res;
01340 }
01341 };
01342
01343
01344 template<typename Other,int Mode, int Options, int Dim, int HDim>
01345 struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, Dim,Dim>
01346 {
01347 typedef Transform<typename Other::Scalar,Dim,Mode,Options> TransformType;
01348 typedef typename TransformType::MatrixType MatrixType;
01349 typedef TransformType ResultType;
01350 static ResultType run(const Other& other, const TransformType& tr)
01351 {
01352 TransformType res;
01353 if(Mode!=int(AffineCompact))
01354 res.matrix().row(Dim) = tr.matrix().row(Dim);
01355 res.matrix().template topRows<Dim>().noalias()
01356 = other * tr.matrix().template topRows<Dim>();
01357 return res;
01358 }
01359 };
01360
01361
01362
01363
01364
01365 template<typename Scalar, int Dim, int LhsMode, int LhsOptions, int RhsMode, int RhsOptions>
01366 struct transform_transform_product_impl<Transform<Scalar,Dim,LhsMode,LhsOptions>,Transform<Scalar,Dim,RhsMode,RhsOptions>,false >
01367 {
01368 enum { ResultMode = transform_product_result<LhsMode,RhsMode>::Mode };
01369 typedef Transform<Scalar,Dim,LhsMode,LhsOptions> Lhs;
01370 typedef Transform<Scalar,Dim,RhsMode,RhsOptions> Rhs;
01371 typedef Transform<Scalar,Dim,ResultMode,LhsOptions> ResultType;
01372 static ResultType run(const Lhs& lhs, const Rhs& rhs)
01373 {
01374 ResultType res;
01375 res.linear() = lhs.linear() * rhs.linear();
01376 res.translation() = lhs.linear() * rhs.translation() + lhs.translation();
01377 res.makeAffine();
01378 return res;
01379 }
01380 };
01381
01382 template<typename Scalar, int Dim, int LhsMode, int LhsOptions, int RhsMode, int RhsOptions>
01383 struct transform_transform_product_impl<Transform<Scalar,Dim,LhsMode,LhsOptions>,Transform<Scalar,Dim,RhsMode,RhsOptions>,true >
01384 {
01385 typedef Transform<Scalar,Dim,LhsMode,LhsOptions> Lhs;
01386 typedef Transform<Scalar,Dim,RhsMode,RhsOptions> Rhs;
01387 typedef Transform<Scalar,Dim,Projective> ResultType;
01388 static ResultType run(const Lhs& lhs, const Rhs& rhs)
01389 {
01390 return ResultType( lhs.matrix() * rhs.matrix() );
01391 }
01392 };
01393
01394 }
01395
01396 #endif // EIGEN_TRANSFORM_H