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 bool IsProjective = transform_traits<TransformType>::IsProjective>
00047 struct transform_right_product_impl;
00048
00049 template< typename Other,
00050 int Mode,
00051 int Options,
00052 int Dim,
00053 int HDim,
00054 int OtherRows=Other::RowsAtCompileTime,
00055 int OtherCols=Other::ColsAtCompileTime>
00056 struct transform_left_product_impl;
00057
00058 template< typename Lhs,
00059 typename Rhs,
00060 bool AnyProjective =
00061 transform_traits<Lhs>::IsProjective ||
00062 transform_traits<Lhs>::IsProjective>
00063 struct transform_transform_product_impl;
00064
00065 template< typename Other,
00066 int Mode,
00067 int Options,
00068 int Dim,
00069 int HDim,
00070 int OtherRows=Other::RowsAtCompileTime,
00071 int OtherCols=Other::ColsAtCompileTime>
00072 struct transform_construct_from_matrix;
00073
00074 template<typename TransformType> struct transform_take_affine_part;
00075
00076 }
00077
00186 template<typename _Scalar, int _Dim, int _Mode, int _Options>
00187 class Transform
00188 {
00189 public:
00190 EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_Dim==Dynamic ? Dynamic : (_Dim+1)*(_Dim+1))
00191 enum {
00192 Mode = _Mode,
00193 Options = _Options,
00194 Dim = _Dim,
00195 HDim = _Dim+1,
00196 Rows = int(Mode)==(AffineCompact) ? Dim : HDim
00197 };
00199 typedef _Scalar Scalar;
00200 typedef DenseIndex Index;
00202 typedef Matrix<Scalar,Rows,HDim,Options> MatrixType;
00204 typedef const MatrixType ConstMatrixType;
00206 typedef Matrix<Scalar,Dim,Dim,Options> LinearMatrixType;
00208 typedef Block<MatrixType,Dim,Dim> LinearPart;
00210 typedef const Block<ConstMatrixType,Dim,Dim> ConstLinearPart;
00212 typedef typename internal::conditional<int(Mode)==int(AffineCompact),
00213 MatrixType&,
00214 Block<MatrixType,Dim,HDim> >::type AffinePart;
00216 typedef typename internal::conditional<int(Mode)==int(AffineCompact),
00217 const MatrixType&,
00218 const Block<const MatrixType,Dim,HDim> >::type ConstAffinePart;
00220 typedef Matrix<Scalar,Dim,1> VectorType;
00222 typedef Block<MatrixType,Dim,1> TranslationPart;
00224 typedef const Block<ConstMatrixType,Dim,1> ConstTranslationPart;
00226 typedef Translation<Scalar,Dim> TranslationType;
00227
00228
00229 enum { TransformTimeDiagonalMode = ((Mode==int(Isometry))?Affine:int(Mode)) };
00231 typedef Transform<Scalar,Dim,TransformTimeDiagonalMode> TransformTimeDiagonalReturnType;
00232
00233 protected:
00234
00235 MatrixType m_matrix;
00236
00237 public:
00238
00241 inline Transform()
00242 {
00243 check_template_params();
00244 if (int(Mode)==Affine)
00245 makeAffine();
00246 }
00247
00248 inline Transform(const Transform& other)
00249 {
00250 check_template_params();
00251 m_matrix = other.m_matrix;
00252 }
00253
00254 inline explicit Transform(const TranslationType& t)
00255 {
00256 check_template_params();
00257 *this = t;
00258 }
00259 inline explicit Transform(const UniformScaling<Scalar>& s)
00260 {
00261 check_template_params();
00262 *this = s;
00263 }
00264 template<typename Derived>
00265 inline explicit Transform(const RotationBase<Derived, Dim>& r)
00266 {
00267 check_template_params();
00268 *this = r;
00269 }
00270
00271 inline Transform& operator=(const Transform& other)
00272 { m_matrix = other.m_matrix; return *this; }
00273
00274 typedef internal::transform_take_affine_part<Transform> take_affine_part;
00275
00277 template<typename OtherDerived>
00278 inline explicit Transform(const EigenBase<OtherDerived>& other)
00279 {
00280 check_template_params();
00281 internal::transform_construct_from_matrix<OtherDerived,Mode,Options,Dim,HDim>::run(this, other.derived());
00282 }
00283
00285 template<typename OtherDerived>
00286 inline Transform& operator=(const EigenBase<OtherDerived>& other)
00287 {
00288 internal::transform_construct_from_matrix<OtherDerived,Mode,Options,Dim,HDim>::run(this, other.derived());
00289 return *this;
00290 }
00291
00292 template<int OtherOptions>
00293 inline Transform(const Transform<Scalar,Dim,Mode,OtherOptions>& other)
00294 {
00295 check_template_params();
00296
00297 m_matrix = other.matrix();
00298 }
00299
00300 template<int OtherMode,int OtherOptions>
00301 inline Transform(const Transform<Scalar,Dim,OtherMode,OtherOptions>& other)
00302 {
00303 check_template_params();
00304
00305
00306 EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(OtherMode==int(Projective), Mode==int(Projective)),
00307 YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION)
00308
00309
00310
00311 EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(OtherMode==int(Affine)||OtherMode==int(AffineCompact), Mode!=int(Isometry)),
00312 YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION)
00313
00314 enum { ModeIsAffineCompact = Mode == int(AffineCompact),
00315 OtherModeIsAffineCompact = OtherMode == int(AffineCompact)
00316 };
00317
00318 if(ModeIsAffineCompact == OtherModeIsAffineCompact)
00319 {
00320
00321
00322
00323 m_matrix.template block<Dim,Dim+1>(0,0) = other.matrix().template block<Dim,Dim+1>(0,0);
00324 makeAffine();
00325 }
00326 else if(OtherModeIsAffineCompact)
00327 {
00328 typedef typename Transform<Scalar,Dim,OtherMode,OtherOptions>::MatrixType OtherMatrixType;
00329 internal::transform_construct_from_matrix<OtherMatrixType,Mode,Options,Dim,HDim>::run(this, other.matrix());
00330 }
00331 else
00332 {
00333
00334
00335
00336 linear() = other.linear();
00337 translation() = other.translation();
00338 }
00339 }
00340
00341 template<typename OtherDerived>
00342 Transform(const ReturnByValue<OtherDerived>& other)
00343 {
00344 check_template_params();
00345 other.evalTo(*this);
00346 }
00347
00348 template<typename OtherDerived>
00349 Transform& operator=(const ReturnByValue<OtherDerived>& other)
00350 {
00351 other.evalTo(*this);
00352 return *this;
00353 }
00354
00355 #ifdef EIGEN_QT_SUPPORT
00356 inline Transform(const QMatrix& other);
00357 inline Transform& operator=(const QMatrix& other);
00358 inline QMatrix toQMatrix(void) const;
00359 inline Transform(const QTransform& other);
00360 inline Transform& operator=(const QTransform& other);
00361 inline QTransform toQTransform(void) const;
00362 #endif
00363
00366 inline Scalar operator() (Index row, Index col) const { return m_matrix(row,col); }
00369 inline Scalar& operator() (Index row, Index col) { return m_matrix(row,col); }
00370
00372 inline const MatrixType& matrix() const { return m_matrix; }
00374 inline MatrixType& matrix() { return m_matrix; }
00375
00377 inline ConstLinearPart linear() const { return m_matrix.template block<Dim,Dim>(0,0); }
00379 inline LinearPart linear() { return m_matrix.template block<Dim,Dim>(0,0); }
00380
00382 inline ConstAffinePart affine() const { return take_affine_part::run(m_matrix); }
00384 inline AffinePart affine() { return take_affine_part::run(m_matrix); }
00385
00387 inline ConstTranslationPart translation() const { return m_matrix.template block<Dim,1>(0,Dim); }
00389 inline TranslationPart translation() { return m_matrix.template block<Dim,1>(0,Dim); }
00390
00402
00403 template<typename OtherDerived>
00404 EIGEN_STRONG_INLINE const typename internal::transform_right_product_impl<Transform, OtherDerived>::ResultType
00405 operator * (const EigenBase<OtherDerived> &other) const
00406 { return internal::transform_right_product_impl<Transform, OtherDerived>::run(*this,other.derived()); }
00407
00415 template<typename OtherDerived> friend
00416 inline const typename internal::transform_left_product_impl<OtherDerived,Mode,Options,_Dim,_Dim+1>::ResultType
00417 operator * (const EigenBase<OtherDerived> &a, const Transform &b)
00418 { return internal::transform_left_product_impl<OtherDerived,Mode,Options,Dim,HDim>::run(a.derived(),b); }
00419
00426 template<typename DiagonalDerived>
00427 inline const TransformTimeDiagonalReturnType
00428 operator * (const DiagonalBase<DiagonalDerived> &b) const
00429 {
00430 TransformTimeDiagonalReturnType res(*this);
00431 res.linear() *= b;
00432 return res;
00433 }
00434
00441 template<typename DiagonalDerived>
00442 friend inline TransformTimeDiagonalReturnType
00443 operator * (const DiagonalBase<DiagonalDerived> &a, const Transform &b)
00444 {
00445 TransformTimeDiagonalReturnType res;
00446 res.linear().noalias() = a*b.linear();
00447 res.translation().noalias() = a*b.translation();
00448 if (Mode!=int(AffineCompact))
00449 res.matrix().row(Dim) = b.matrix().row(Dim);
00450 return res;
00451 }
00452
00453 template<typename OtherDerived>
00454 inline Transform& operator*=(const EigenBase<OtherDerived>& other) { return *this = *this * other; }
00455
00457 inline const Transform operator * (const Transform& other) const
00458 {
00459 return internal::transform_transform_product_impl<Transform,Transform>::run(*this,other);
00460 }
00461
00463 template<int OtherMode,int OtherOptions>
00464 inline const typename internal::transform_transform_product_impl<
00465 Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> >::ResultType
00466 operator * (const Transform<Scalar,Dim,OtherMode,OtherOptions>& other) const
00467 {
00468 return internal::transform_transform_product_impl<Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> >::run(*this,other);
00469 }
00470
00472 void setIdentity() { m_matrix.setIdentity(); }
00473
00478 static const Transform Identity()
00479 {
00480 return Transform(MatrixType::Identity());
00481 }
00482
00483 template<typename OtherDerived>
00484 inline Transform& scale(const MatrixBase<OtherDerived> &other);
00485
00486 template<typename OtherDerived>
00487 inline Transform& prescale(const MatrixBase<OtherDerived> &other);
00488
00489 inline Transform& scale(Scalar s);
00490 inline Transform& prescale(Scalar s);
00491
00492 template<typename OtherDerived>
00493 inline Transform& translate(const MatrixBase<OtherDerived> &other);
00494
00495 template<typename OtherDerived>
00496 inline Transform& pretranslate(const MatrixBase<OtherDerived> &other);
00497
00498 template<typename RotationType>
00499 inline Transform& rotate(const RotationType& rotation);
00500
00501 template<typename RotationType>
00502 inline Transform& prerotate(const RotationType& rotation);
00503
00504 Transform& shear(Scalar sx, Scalar sy);
00505 Transform& preshear(Scalar sx, Scalar sy);
00506
00507 inline Transform& operator=(const TranslationType& t);
00508 inline Transform& operator*=(const TranslationType& t) { return translate(t.vector()); }
00509 inline Transform operator*(const TranslationType& t) const;
00510
00511 inline Transform& operator=(const UniformScaling<Scalar>& t);
00512 inline Transform& operator*=(const UniformScaling<Scalar>& s) { return scale(s.factor()); }
00513 inline Transform operator*(const UniformScaling<Scalar>& s) const;
00514
00515 inline Transform& operator*=(const DiagonalMatrix<Scalar,Dim>& s) { linear() *= s; return *this; }
00516
00517 template<typename Derived>
00518 inline Transform& operator=(const RotationBase<Derived,Dim>& r);
00519 template<typename Derived>
00520 inline Transform& operator*=(const RotationBase<Derived,Dim>& r) { return rotate(r.toRotationMatrix()); }
00521 template<typename Derived>
00522 inline Transform operator*(const RotationBase<Derived,Dim>& r) const;
00523
00524 const LinearMatrixType rotation() const;
00525 template<typename RotationMatrixType, typename ScalingMatrixType>
00526 void computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const;
00527 template<typename ScalingMatrixType, typename RotationMatrixType>
00528 void computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const;
00529
00530 template<typename PositionDerived, typename OrientationType, typename ScaleDerived>
00531 Transform& fromPositionOrientationScale(const MatrixBase<PositionDerived> &position,
00532 const OrientationType& orientation, const MatrixBase<ScaleDerived> &scale);
00533
00534 inline Transform inverse(TransformTraits traits = (TransformTraits)Mode) const;
00535
00537 const Scalar* data() const { return m_matrix.data(); }
00539 Scalar* data() { return m_matrix.data(); }
00540
00546 template<typename NewScalarType>
00547 inline typename internal::cast_return_type<Transform,Transform<NewScalarType,Dim,Mode,Options> >::type cast() const
00548 { return typename internal::cast_return_type<Transform,Transform<NewScalarType,Dim,Mode,Options> >::type(*this); }
00549
00551 template<typename OtherScalarType>
00552 inline explicit Transform(const Transform<OtherScalarType,Dim,Mode,Options>& other)
00553 {
00554 check_template_params();
00555 m_matrix = other.matrix().template cast<Scalar>();
00556 }
00557
00562 bool isApprox(const Transform& other, typename NumTraits<Scalar>::Real prec = NumTraits<Scalar>::dummy_precision()) const
00563 { return m_matrix.isApprox(other.m_matrix, prec); }
00564
00567 void makeAffine()
00568 {
00569 if(int(Mode)!=int(AffineCompact))
00570 {
00571 matrix().template block<1,Dim>(Dim,0).setZero();
00572 matrix().coeffRef(Dim,Dim) = 1;
00573 }
00574 }
00575
00580 inline Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,Dim> linearExt()
00581 { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,Dim>(0,0); }
00586 inline const Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,Dim> linearExt() const
00587 { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,Dim>(0,0); }
00588
00593 inline Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,1> translationExt()
00594 { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,1>(0,Dim); }
00599 inline const Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,1> translationExt() const
00600 { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,1>(0,Dim); }
00601
00602
00603 #ifdef EIGEN_TRANSFORM_PLUGIN
00604 #include EIGEN_TRANSFORM_PLUGIN
00605 #endif
00606
00607 protected:
00608 #ifndef EIGEN_PARSED_BY_DOXYGEN
00609 EIGEN_STRONG_INLINE static void check_template_params()
00610 {
00611 EIGEN_STATIC_ASSERT((Options & (DontAlign|RowMajor)) == Options, INVALID_MATRIX_TEMPLATE_PARAMETERS)
00612 }
00613 #endif
00614
00615 };
00616
00618 typedef Transform<float,2,Isometry> Isometry2f;
00620 typedef Transform<float,3,Isometry> Isometry3f;
00622 typedef Transform<double,2,Isometry> Isometry2d;
00624 typedef Transform<double,3,Isometry> Isometry3d;
00625
00627 typedef Transform<float,2,Affine> Affine2f;
00629 typedef Transform<float,3,Affine> Affine3f;
00631 typedef Transform<double,2,Affine> Affine2d;
00633 typedef Transform<double,3,Affine> Affine3d;
00634
00636 typedef Transform<float,2,AffineCompact> AffineCompact2f;
00638 typedef Transform<float,3,AffineCompact> AffineCompact3f;
00640 typedef Transform<double,2,AffineCompact> AffineCompact2d;
00642 typedef Transform<double,3,AffineCompact> AffineCompact3d;
00643
00645 typedef Transform<float,2,Projective> Projective2f;
00647 typedef Transform<float,3,Projective> Projective3f;
00649 typedef Transform<double,2,Projective> Projective2d;
00651 typedef Transform<double,3,Projective> Projective3d;
00652
00653
00654
00655
00656
00657 #ifdef EIGEN_QT_SUPPORT
00658
00662 template<typename Scalar, int Dim, int Mode,int Options>
00663 Transform<Scalar,Dim,Mode,Options>::Transform(const QMatrix& other)
00664 {
00665 check_template_params();
00666 *this = other;
00667 }
00668
00673 template<typename Scalar, int Dim, int Mode,int Otpions>
00674 Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const QMatrix& other)
00675 {
00676 EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00677 m_matrix << other.m11(), other.m21(), other.dx(),
00678 other.m12(), other.m22(), other.dy(),
00679 0, 0, 1;
00680 return *this;
00681 }
00682
00689 template<typename Scalar, int Dim, int Mode, int Options>
00690 QMatrix Transform<Scalar,Dim,Mode,Options>::toQMatrix(void) const
00691 {
00692 check_template_params();
00693 EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00694 return QMatrix(m_matrix.coeff(0,0), m_matrix.coeff(1,0),
00695 m_matrix.coeff(0,1), m_matrix.coeff(1,1),
00696 m_matrix.coeff(0,2), m_matrix.coeff(1,2));
00697 }
00698
00703 template<typename Scalar, int Dim, int Mode,int Options>
00704 Transform<Scalar,Dim,Mode,Options>::Transform(const QTransform& other)
00705 {
00706 check_template_params();
00707 *this = other;
00708 }
00709
00714 template<typename Scalar, int Dim, int Mode, int Options>
00715 Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const QTransform& other)
00716 {
00717 check_template_params();
00718 EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00719 m_matrix << other.m11(), other.m21(), other.dx(),
00720 other.m12(), other.m22(), other.dy(),
00721 other.m13(), other.m23(), other.m33();
00722 return *this;
00723 }
00724
00729 template<typename Scalar, int Dim, int Mode, int Options>
00730 QTransform Transform<Scalar,Dim,Mode,Options>::toQTransform(void) const
00731 {
00732 EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00733 return QTransform(matrix.coeff(0,0), matrix.coeff(1,0), matrix.coeff(2,0)
00734 matrix.coeff(0,1), matrix.coeff(1,1), matrix.coeff(2,1)
00735 matrix.coeff(0,2), matrix.coeff(1,2), matrix.coeff(2,2));
00736 }
00737 #endif
00738
00739
00740
00741
00742
00747 template<typename Scalar, int Dim, int Mode, int Options>
00748 template<typename OtherDerived>
00749 Transform<Scalar,Dim,Mode,Options>&
00750 Transform<Scalar,Dim,Mode,Options>::scale(const MatrixBase<OtherDerived> &other)
00751 {
00752 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
00753 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
00754 linearExt().noalias() = (linearExt() * other.asDiagonal());
00755 return *this;
00756 }
00757
00762 template<typename Scalar, int Dim, int Mode, int Options>
00763 inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::scale(Scalar s)
00764 {
00765 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
00766 linearExt() *= s;
00767 return *this;
00768 }
00769
00774 template<typename Scalar, int Dim, int Mode, int Options>
00775 template<typename OtherDerived>
00776 Transform<Scalar,Dim,Mode,Options>&
00777 Transform<Scalar,Dim,Mode,Options>::prescale(const MatrixBase<OtherDerived> &other)
00778 {
00779 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
00780 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
00781 m_matrix.template block<Dim,HDim>(0,0).noalias() = (other.asDiagonal() * m_matrix.template block<Dim,HDim>(0,0));
00782 return *this;
00783 }
00784
00789 template<typename Scalar, int Dim, int Mode, int Options>
00790 inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::prescale(Scalar s)
00791 {
00792 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
00793 m_matrix.template topRows<Dim>() *= s;
00794 return *this;
00795 }
00796
00801 template<typename Scalar, int Dim, int Mode, int Options>
00802 template<typename OtherDerived>
00803 Transform<Scalar,Dim,Mode,Options>&
00804 Transform<Scalar,Dim,Mode,Options>::translate(const MatrixBase<OtherDerived> &other)
00805 {
00806 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
00807 translationExt() += linearExt() * other;
00808 return *this;
00809 }
00810
00815 template<typename Scalar, int Dim, int Mode, int Options>
00816 template<typename OtherDerived>
00817 Transform<Scalar,Dim,Mode,Options>&
00818 Transform<Scalar,Dim,Mode,Options>::pretranslate(const MatrixBase<OtherDerived> &other)
00819 {
00820 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
00821 if(int(Mode)==int(Projective))
00822 affine() += other * m_matrix.row(Dim);
00823 else
00824 translation() += other;
00825 return *this;
00826 }
00827
00845 template<typename Scalar, int Dim, int Mode, int Options>
00846 template<typename RotationType>
00847 Transform<Scalar,Dim,Mode,Options>&
00848 Transform<Scalar,Dim,Mode,Options>::rotate(const RotationType& rotation)
00849 {
00850 linearExt() *= internal::toRotationMatrix<Scalar,Dim>(rotation);
00851 return *this;
00852 }
00853
00861 template<typename Scalar, int Dim, int Mode, int Options>
00862 template<typename RotationType>
00863 Transform<Scalar,Dim,Mode,Options>&
00864 Transform<Scalar,Dim,Mode,Options>::prerotate(const RotationType& rotation)
00865 {
00866 m_matrix.template block<Dim,HDim>(0,0) = internal::toRotationMatrix<Scalar,Dim>(rotation)
00867 * m_matrix.template block<Dim,HDim>(0,0);
00868 return *this;
00869 }
00870
00876 template<typename Scalar, int Dim, int Mode, int Options>
00877 Transform<Scalar,Dim,Mode,Options>&
00878 Transform<Scalar,Dim,Mode,Options>::shear(Scalar sx, Scalar sy)
00879 {
00880 EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00881 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
00882 VectorType tmp = linear().col(0)*sy + linear().col(1);
00883 linear() << linear().col(0) + linear().col(1)*sx, tmp;
00884 return *this;
00885 }
00886
00892 template<typename Scalar, int Dim, int Mode, int Options>
00893 Transform<Scalar,Dim,Mode,Options>&
00894 Transform<Scalar,Dim,Mode,Options>::preshear(Scalar sx, Scalar sy)
00895 {
00896 EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00897 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
00898 m_matrix.template block<Dim,HDim>(0,0) = LinearMatrixType(1, sx, sy, 1) * m_matrix.template block<Dim,HDim>(0,0);
00899 return *this;
00900 }
00901
00902
00903
00904
00905
00906 template<typename Scalar, int Dim, int Mode, int Options>
00907 inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const TranslationType& t)
00908 {
00909 linear().setIdentity();
00910 translation() = t.vector();
00911 makeAffine();
00912 return *this;
00913 }
00914
00915 template<typename Scalar, int Dim, int Mode, int Options>
00916 inline Transform<Scalar,Dim,Mode,Options> Transform<Scalar,Dim,Mode,Options>::operator*(const TranslationType& t) const
00917 {
00918 Transform res = *this;
00919 res.translate(t.vector());
00920 return res;
00921 }
00922
00923 template<typename Scalar, int Dim, int Mode, int Options>
00924 inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const UniformScaling<Scalar>& s)
00925 {
00926 m_matrix.setZero();
00927 linear().diagonal().fill(s.factor());
00928 makeAffine();
00929 return *this;
00930 }
00931
00932 template<typename Scalar, int Dim, int Mode, int Options>
00933 inline Transform<Scalar,Dim,Mode,Options> Transform<Scalar,Dim,Mode,Options>::operator*(const UniformScaling<Scalar>& s) const
00934 {
00935 Transform res = *this;
00936 res.scale(s.factor());
00937 return res;
00938 }
00939
00940 template<typename Scalar, int Dim, int Mode, int Options>
00941 template<typename Derived>
00942 inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const RotationBase<Derived,Dim>& r)
00943 {
00944 linear() = internal::toRotationMatrix<Scalar,Dim>(r);
00945 translation().setZero();
00946 makeAffine();
00947 return *this;
00948 }
00949
00950 template<typename Scalar, int Dim, int Mode, int Options>
00951 template<typename Derived>
00952 inline Transform<Scalar,Dim,Mode,Options> Transform<Scalar,Dim,Mode,Options>::operator*(const RotationBase<Derived,Dim>& r) const
00953 {
00954 Transform res = *this;
00955 res.rotate(r.derived());
00956 return res;
00957 }
00958
00959
00960
00961
00962
00970 template<typename Scalar, int Dim, int Mode, int Options>
00971 const typename Transform<Scalar,Dim,Mode,Options>::LinearMatrixType
00972 Transform<Scalar,Dim,Mode,Options>::rotation() const
00973 {
00974 LinearMatrixType result;
00975 computeRotationScaling(&result, (LinearMatrixType*)0);
00976 return result;
00977 }
00978
00979
00991 template<typename Scalar, int Dim, int Mode, int Options>
00992 template<typename RotationMatrixType, typename ScalingMatrixType>
00993 void Transform<Scalar,Dim,Mode,Options>::computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const
00994 {
00995 JacobiSVD<LinearMatrixType> svd(linear(), ComputeFullU | ComputeFullV);
00996
00997 Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant();
00998 VectorType sv(svd.singularValues());
00999 sv.coeffRef(0) *= x;
01000 if(scaling) scaling->lazyAssign(svd.matrixV() * sv.asDiagonal() * svd.matrixV().adjoint());
01001 if(rotation)
01002 {
01003 LinearMatrixType m(svd.matrixU());
01004 m.col(0) /= x;
01005 rotation->lazyAssign(m * svd.matrixV().adjoint());
01006 }
01007 }
01008
01020 template<typename Scalar, int Dim, int Mode, int Options>
01021 template<typename ScalingMatrixType, typename RotationMatrixType>
01022 void Transform<Scalar,Dim,Mode,Options>::computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const
01023 {
01024 JacobiSVD<LinearMatrixType> svd(linear(), ComputeFullU | ComputeFullV);
01025
01026 Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant();
01027 VectorType sv(svd.singularValues());
01028 sv.coeffRef(0) *= x;
01029 if(scaling) scaling->lazyAssign(svd.matrixU() * sv.asDiagonal() * svd.matrixU().adjoint());
01030 if(rotation)
01031 {
01032 LinearMatrixType m(svd.matrixU());
01033 m.col(0) /= x;
01034 rotation->lazyAssign(m * svd.matrixV().adjoint());
01035 }
01036 }
01037
01041 template<typename Scalar, int Dim, int Mode, int Options>
01042 template<typename PositionDerived, typename OrientationType, typename ScaleDerived>
01043 Transform<Scalar,Dim,Mode,Options>&
01044 Transform<Scalar,Dim,Mode,Options>::fromPositionOrientationScale(const MatrixBase<PositionDerived> &position,
01045 const OrientationType& orientation, const MatrixBase<ScaleDerived> &scale)
01046 {
01047 linear() = internal::toRotationMatrix<Scalar,Dim>(orientation);
01048 linear() *= scale.asDiagonal();
01049 translation() = position;
01050 makeAffine();
01051 return *this;
01052 }
01053
01054 namespace internal {
01055
01056
01057 template<typename TransformType, int Mode=TransformType::Mode>
01058 struct projective_transform_inverse
01059 {
01060 static inline void run(const TransformType&, TransformType&)
01061 {}
01062 };
01063
01064 template<typename TransformType>
01065 struct projective_transform_inverse<TransformType, Projective>
01066 {
01067 static inline void run(const TransformType& m, TransformType& res)
01068 {
01069 res.matrix() = m.matrix().inverse();
01070 }
01071 };
01072
01073 }
01074
01075
01096 template<typename Scalar, int Dim, int Mode, int Options>
01097 Transform<Scalar,Dim,Mode,Options>
01098 Transform<Scalar,Dim,Mode,Options>::inverse(TransformTraits hint) const
01099 {
01100 Transform res;
01101 if (hint == Projective)
01102 {
01103 internal::projective_transform_inverse<Transform>::run(*this, res);
01104 }
01105 else
01106 {
01107 if (hint == Isometry)
01108 {
01109 res.matrix().template topLeftCorner<Dim,Dim>() = linear().transpose();
01110 }
01111 else if(hint&Affine)
01112 {
01113 res.matrix().template topLeftCorner<Dim,Dim>() = linear().inverse();
01114 }
01115 else
01116 {
01117 eigen_assert(false && "Invalid transform traits in Transform::Inverse");
01118 }
01119
01120 res.matrix().template topRightCorner<Dim,1>()
01121 = - res.matrix().template topLeftCorner<Dim,Dim>() * translation();
01122 res.makeAffine();
01123 }
01124 return res;
01125 }
01126
01127 namespace internal {
01128
01129
01130
01131
01132
01133 template<typename TransformType> struct transform_take_affine_part {
01134 typedef typename TransformType::MatrixType MatrixType;
01135 typedef typename TransformType::AffinePart AffinePart;
01136 typedef typename TransformType::ConstAffinePart ConstAffinePart;
01137 static inline AffinePart run(MatrixType& m)
01138 { return m.template block<TransformType::Dim,TransformType::HDim>(0,0); }
01139 static inline ConstAffinePart run(const MatrixType& m)
01140 { return m.template block<TransformType::Dim,TransformType::HDim>(0,0); }
01141 };
01142
01143 template<typename Scalar, int Dim, int Options>
01144 struct transform_take_affine_part<Transform<Scalar,Dim,AffineCompact, Options> > {
01145 typedef typename Transform<Scalar,Dim,AffineCompact,Options>::MatrixType MatrixType;
01146 static inline MatrixType& run(MatrixType& m) { return m; }
01147 static inline const MatrixType& run(const MatrixType& m) { return m; }
01148 };
01149
01150
01151
01152
01153
01154 template<typename Other, int Mode, int Options, int Dim, int HDim>
01155 struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, Dim,Dim>
01156 {
01157 static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other)
01158 {
01159 transform->linear() = other;
01160 transform->translation().setZero();
01161 transform->makeAffine();
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,HDim>
01167 {
01168 static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other)
01169 {
01170 transform->affine() = other;
01171 transform->makeAffine();
01172 }
01173 };
01174
01175 template<typename Other, int Mode, int Options, int Dim, int HDim>
01176 struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, HDim,HDim>
01177 {
01178 static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other)
01179 { transform->matrix() = other; }
01180 };
01181
01182 template<typename Other, int Options, int Dim, int HDim>
01183 struct transform_construct_from_matrix<Other, AffineCompact,Options,Dim,HDim, HDim,HDim>
01184 {
01185 static inline void run(Transform<typename Other::Scalar,Dim,AffineCompact,Options> *transform, const Other& other)
01186 { transform->matrix() = other.template block<Dim,HDim>(0,0); }
01187 };
01188
01189
01190
01191
01192
01193 template<int LhsMode,int RhsMode>
01194 struct transform_product_result
01195 {
01196 enum
01197 {
01198 Mode =
01199 (LhsMode == (int)Projective || RhsMode == (int)Projective ) ? Projective :
01200 (LhsMode == (int)Affine || RhsMode == (int)Affine ) ? Affine :
01201 (LhsMode == (int)AffineCompact || RhsMode == (int)AffineCompact ) ? AffineCompact :
01202 (LhsMode == (int)Isometry || RhsMode == (int)Isometry ) ? Isometry : Projective
01203 };
01204 };
01205
01206 template< typename TransformType, typename MatrixType >
01207 struct transform_right_product_impl< TransformType, MatrixType, true >
01208 {
01209 typedef typename MatrixType::PlainObject ResultType;
01210
01211 EIGEN_STRONG_INLINE static ResultType run(const TransformType& T, const MatrixType& other)
01212 {
01213 return T.matrix() * other;
01214 }
01215 };
01216
01217 template< typename TransformType, typename MatrixType >
01218 struct transform_right_product_impl< TransformType, MatrixType, false >
01219 {
01220 enum {
01221 Dim = TransformType::Dim,
01222 HDim = TransformType::HDim,
01223 OtherRows = MatrixType::RowsAtCompileTime,
01224 OtherCols = MatrixType::ColsAtCompileTime
01225 };
01226
01227 typedef typename MatrixType::PlainObject ResultType;
01228
01229 EIGEN_STRONG_INLINE static ResultType run(const TransformType& T, const MatrixType& other)
01230 {
01231 EIGEN_STATIC_ASSERT(OtherRows==Dim || OtherRows==HDim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);
01232
01233 typedef Block<ResultType, Dim, OtherCols> TopLeftLhs;
01234 typedef Block<const MatrixType, Dim, OtherCols> TopLeftRhs;
01235
01236 ResultType res(other.rows(),other.cols());
01237
01238 TopLeftLhs(res, 0, 0, Dim, other.cols()) =
01239 ( T.linear() * TopLeftRhs(other, 0, 0, Dim, other.cols()) ).colwise() +
01240 T.translation();
01241
01242
01243 if (OtherRows==HDim)
01244 res.row(other.rows()) = other.row(other.rows());
01245
01246 return res;
01247 }
01248 };
01249
01250
01251
01252
01253
01254
01255 template<typename Other,int Mode, int Options, int Dim, int HDim>
01256 struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, HDim,HDim>
01257 {
01258 typedef Transform<typename Other::Scalar,Dim,Mode,Options> TransformType;
01259 typedef typename TransformType::MatrixType MatrixType;
01260 typedef Transform<typename Other::Scalar,Dim,Projective,Options> ResultType;
01261 static ResultType run(const Other& other,const TransformType& tr)
01262 { return ResultType(other * tr.matrix()); }
01263 };
01264
01265
01266 template<typename Other, int Options, int Dim, int HDim>
01267 struct transform_left_product_impl<Other,AffineCompact,Options,Dim,HDim, HDim,HDim>
01268 {
01269 typedef Transform<typename Other::Scalar,Dim,AffineCompact,Options> TransformType;
01270 typedef typename TransformType::MatrixType MatrixType;
01271 typedef Transform<typename Other::Scalar,Dim,Projective,Options> ResultType;
01272 static ResultType run(const Other& other,const TransformType& tr)
01273 {
01274 ResultType res;
01275 res.matrix().noalias() = other.template block<HDim,Dim>(0,0) * tr.matrix();
01276 res.matrix().col(Dim) += other.col(Dim);
01277 return res;
01278 }
01279 };
01280
01281
01282 template<typename Other,int Mode, int Options, int Dim, int HDim>
01283 struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, Dim,HDim>
01284 {
01285 typedef Transform<typename Other::Scalar,Dim,Mode,Options> TransformType;
01286 typedef typename TransformType::MatrixType MatrixType;
01287 typedef TransformType ResultType;
01288 static ResultType run(const Other& other,const TransformType& tr)
01289 {
01290 ResultType res;
01291 res.affine().noalias() = other * tr.matrix();
01292 res.matrix().row(Dim) = tr.matrix().row(Dim);
01293 return res;
01294 }
01295 };
01296
01297
01298 template<typename Other, int Options, int Dim, int HDim>
01299 struct transform_left_product_impl<Other,AffineCompact,Options,Dim,HDim, Dim,HDim>
01300 {
01301 typedef Transform<typename Other::Scalar,Dim,AffineCompact,Options> TransformType;
01302 typedef typename TransformType::MatrixType MatrixType;
01303 typedef TransformType ResultType;
01304 static ResultType run(const Other& other,const TransformType& tr)
01305 {
01306 ResultType res;
01307 res.matrix().noalias() = other.template block<Dim,Dim>(0,0) * tr.matrix();
01308 res.translation() += other.col(Dim);
01309 return res;
01310 }
01311 };
01312
01313
01314 template<typename Other,int Mode, int Options, int Dim, int HDim>
01315 struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, Dim,Dim>
01316 {
01317 typedef Transform<typename Other::Scalar,Dim,Mode,Options> TransformType;
01318 typedef typename TransformType::MatrixType MatrixType;
01319 typedef TransformType ResultType;
01320 static ResultType run(const Other& other, const TransformType& tr)
01321 {
01322 TransformType res;
01323 if(Mode!=int(AffineCompact))
01324 res.matrix().row(Dim) = tr.matrix().row(Dim);
01325 res.matrix().template topRows<Dim>().noalias()
01326 = other * tr.matrix().template topRows<Dim>();
01327 return res;
01328 }
01329 };
01330
01331
01332
01333
01334
01335 template<typename Scalar, int Dim, int LhsMode, int LhsOptions, int RhsMode, int RhsOptions>
01336 struct transform_transform_product_impl<Transform<Scalar,Dim,LhsMode,LhsOptions>,Transform<Scalar,Dim,RhsMode,RhsOptions>,false >
01337 {
01338 enum { ResultMode = transform_product_result<LhsMode,RhsMode>::Mode };
01339 typedef Transform<Scalar,Dim,LhsMode,LhsOptions> Lhs;
01340 typedef Transform<Scalar,Dim,RhsMode,RhsOptions> Rhs;
01341 typedef Transform<Scalar,Dim,ResultMode,LhsOptions> ResultType;
01342 static ResultType run(const Lhs& lhs, const Rhs& rhs)
01343 {
01344 ResultType res;
01345 res.linear() = lhs.linear() * rhs.linear();
01346 res.translation() = lhs.linear() * rhs.translation() + lhs.translation();
01347 res.makeAffine();
01348 return res;
01349 }
01350 };
01351
01352 template<typename Scalar, int Dim, int LhsMode, int LhsOptions, int RhsMode, int RhsOptions>
01353 struct transform_transform_product_impl<Transform<Scalar,Dim,LhsMode,LhsOptions>,Transform<Scalar,Dim,RhsMode,RhsOptions>,true >
01354 {
01355 typedef Transform<Scalar,Dim,LhsMode,LhsOptions> Lhs;
01356 typedef Transform<Scalar,Dim,RhsMode,RhsOptions> Rhs;
01357 typedef Transform<Scalar,Dim,Projective> ResultType;
01358 static ResultType run(const Lhs& lhs, const Rhs& rhs)
01359 {
01360 return ResultType( lhs.matrix() * rhs.matrix() );
01361 }
01362 };
01363
01364 }
01365
01366 #endif // EIGEN_TRANSFORM_H