MOAB
4.9.3pre
|
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2008 Gael Guennebaud <[email protected]> 00005 // Copyright (C) 2009 Benoit Jacob <[email protected]> 00006 // Copyright (C) 2010 Hauke Heibel <[email protected]> 00007 // 00008 // This Source Code Form is subject to the terms of the Mozilla 00009 // Public License v. 2.0. If a copy of the MPL was not distributed 00010 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 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<typename _Scalar, int _Dim, int _Mode, int _Options> 00066 struct traits<Transform<_Scalar,_Dim,_Mode,_Options> > 00067 { 00068 typedef _Scalar Scalar; 00069 typedef Eigen::Index StorageIndex; 00070 typedef Dense StorageKind; 00071 enum { 00072 Dim1 = _Dim==Dynamic ? _Dim : _Dim + 1, 00073 RowsAtCompileTime = _Mode==Projective ? Dim1 : _Dim, 00074 ColsAtCompileTime = Dim1, 00075 MaxRowsAtCompileTime = RowsAtCompileTime, 00076 MaxColsAtCompileTime = ColsAtCompileTime, 00077 Flags = 0 00078 }; 00079 }; 00080 00081 template<int Mode> struct transform_make_affine; 00082 00083 } // end namespace internal 00084 00199 template<typename _Scalar, int _Dim, int _Mode, int _Options> 00200 class Transform 00201 { 00202 public: 00203 EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_Dim==Dynamic ? Dynamic : (_Dim+1)*(_Dim+1)) 00204 enum { 00205 Mode = _Mode, 00206 Options = _Options, 00207 Dim = _Dim, 00208 HDim = _Dim+1, 00209 Rows = int(Mode)==(AffineCompact) ? Dim : HDim 00210 }; 00212 typedef _Scalar Scalar; 00213 typedef Eigen::Index StorageIndex; 00214 typedef Eigen::Index Index; 00215 00216 typedef typename internal::make_proper_matrix_type<Scalar,Rows,HDim,Options>::type MatrixType; 00218 typedef const MatrixType ConstMatrixType; 00220 typedef Matrix<Scalar,Dim,Dim,Options> LinearMatrixType; 00222 typedef Block<MatrixType,Dim,Dim,int(Mode)==(AffineCompact) && (Options&RowMajor)==0> LinearPart; 00224 typedef const Block<ConstMatrixType,Dim,Dim,int(Mode)==(AffineCompact) && (Options&RowMajor)==0> ConstLinearPart; 00226 typedef typename internal::conditional<int(Mode)==int(AffineCompact), 00227 MatrixType&, 00228 Block<MatrixType,Dim,HDim> >::type AffinePart; 00230 typedef typename internal::conditional<int(Mode)==int(AffineCompact), 00231 const MatrixType&, 00232 const Block<const MatrixType,Dim,HDim> >::type ConstAffinePart; 00234 typedef Matrix<Scalar,Dim,1> VectorType; 00236 typedef Block<MatrixType,Dim,1,!(internal::traits<MatrixType>::Flags & RowMajorBit)> TranslationPart; 00238 typedef const Block<ConstMatrixType,Dim,1,!(internal::traits<MatrixType>::Flags & RowMajorBit)> ConstTranslationPart; 00240 typedef Translation<Scalar,Dim> TranslationType; 00241 00242 // this intermediate enum is needed to avoid an ICE with gcc 3.4 and 4.0 00243 enum { TransformTimeDiagonalMode = ((Mode==int(Isometry))?Affine:int(Mode)) }; 00245 typedef Transform<Scalar,Dim,TransformTimeDiagonalMode> TransformTimeDiagonalReturnType; 00246 00247 protected: 00248 00249 MatrixType m_matrix; 00250 00251 public: 00252 00255 inline Transform() 00256 { 00257 check_template_params(); 00258 internal::transform_make_affine<(int(Mode)==Affine) ? Affine : AffineCompact>::run(m_matrix); 00259 } 00260 00261 inline Transform(const Transform& other) 00262 { 00263 check_template_params(); 00264 m_matrix = other.m_matrix; 00265 } 00266 00267 inline explicit Transform(const TranslationType& t) 00268 { 00269 check_template_params(); 00270 *this = t; 00271 } 00272 inline explicit Transform(const UniformScaling<Scalar>& s) 00273 { 00274 check_template_params(); 00275 *this = s; 00276 } 00277 template<typename Derived> 00278 inline explicit Transform(const RotationBase<Derived, Dim>& r) 00279 { 00280 check_template_params(); 00281 *this = r; 00282 } 00283 00284 inline Transform& operator=(const Transform& other) 00285 { m_matrix = other.m_matrix; return *this; } 00286 00287 typedef internal::transform_take_affine_part<Transform> take_affine_part; 00288 00290 template<typename OtherDerived> 00291 inline explicit Transform(const EigenBase<OtherDerived>& other) 00292 { 00293 EIGEN_STATIC_ASSERT((internal::is_same<Scalar,typename OtherDerived::Scalar>::value), 00294 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY); 00295 00296 check_template_params(); 00297 internal::transform_construct_from_matrix<OtherDerived,Mode,Options,Dim,HDim>::run(this, other.derived()); 00298 } 00299 00301 template<typename OtherDerived> 00302 inline Transform& operator=(const EigenBase<OtherDerived>& other) 00303 { 00304 EIGEN_STATIC_ASSERT((internal::is_same<Scalar,typename OtherDerived::Scalar>::value), 00305 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY); 00306 00307 internal::transform_construct_from_matrix<OtherDerived,Mode,Options,Dim,HDim>::run(this, other.derived()); 00308 return *this; 00309 } 00310 00311 template<int OtherOptions> 00312 inline Transform(const Transform<Scalar,Dim,Mode,OtherOptions>& other) 00313 { 00314 check_template_params(); 00315 // only the options change, we can directly copy the matrices 00316 m_matrix = other.matrix(); 00317 } 00318 00319 template<int OtherMode,int OtherOptions> 00320 inline Transform(const Transform<Scalar,Dim,OtherMode,OtherOptions>& other) 00321 { 00322 check_template_params(); 00323 // prevent conversions as: 00324 // Affine | AffineCompact | Isometry = Projective 00325 EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(OtherMode==int(Projective), Mode==int(Projective)), 00326 YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION) 00327 00328 // prevent conversions as: 00329 // Isometry = Affine | AffineCompact 00330 EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(OtherMode==int(Affine)||OtherMode==int(AffineCompact), Mode!=int(Isometry)), 00331 YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION) 00332 00333 enum { ModeIsAffineCompact = Mode == int(AffineCompact), 00334 OtherModeIsAffineCompact = OtherMode == int(AffineCompact) 00335 }; 00336 00337 if(ModeIsAffineCompact == OtherModeIsAffineCompact) 00338 { 00339 // We need the block expression because the code is compiled for all 00340 // combinations of transformations and will trigger a compile time error 00341 // if one tries to assign the matrices directly 00342 m_matrix.template block<Dim,Dim+1>(0,0) = other.matrix().template block<Dim,Dim+1>(0,0); 00343 makeAffine(); 00344 } 00345 else if(OtherModeIsAffineCompact) 00346 { 00347 typedef typename Transform<Scalar,Dim,OtherMode,OtherOptions>::MatrixType OtherMatrixType; 00348 internal::transform_construct_from_matrix<OtherMatrixType,Mode,Options,Dim,HDim>::run(this, other.matrix()); 00349 } 00350 else 00351 { 00352 // here we know that Mode == AffineCompact and OtherMode != AffineCompact. 00353 // if OtherMode were Projective, the static assert above would already have caught it. 00354 // So the only possibility is that OtherMode == Affine 00355 linear() = other.linear(); 00356 translation() = other.translation(); 00357 } 00358 } 00359 00360 template<typename OtherDerived> 00361 Transform(const ReturnByValue<OtherDerived>& other) 00362 { 00363 check_template_params(); 00364 other.evalTo(*this); 00365 } 00366 00367 template<typename OtherDerived> 00368 Transform& operator=(const ReturnByValue<OtherDerived>& other) 00369 { 00370 other.evalTo(*this); 00371 return *this; 00372 } 00373 00374 #ifdef EIGEN_QT_SUPPORT 00375 inline Transform(const QMatrix& other); 00376 inline Transform& operator=(const QMatrix& other); 00377 inline QMatrix toQMatrix(void) const; 00378 inline Transform(const QTransform& other); 00379 inline Transform& operator=(const QTransform& other); 00380 inline QTransform toQTransform(void) const; 00381 #endif 00382 00383 Index rows() const { return int(Mode)==int(Projective) ? m_matrix.cols() : (m_matrix.cols()-1); } 00384 Index cols() const { return m_matrix.cols(); } 00385 00388 inline Scalar operator() (Index row, Index col) const { return m_matrix(row,col); } 00391 inline Scalar& operator() (Index row, Index col) { return m_matrix(row,col); } 00392 00394 inline const MatrixType& matrix() const { return m_matrix; } 00396 inline MatrixType& matrix() { return m_matrix; } 00397 00399 inline ConstLinearPart linear() const { return ConstLinearPart(m_matrix,0,0); } 00401 inline LinearPart linear() { return LinearPart(m_matrix,0,0); } 00402 00404 inline ConstAffinePart affine() const { return take_affine_part::run(m_matrix); } 00406 inline AffinePart affine() { return take_affine_part::run(m_matrix); } 00407 00409 inline ConstTranslationPart translation() const { return ConstTranslationPart(m_matrix,0,Dim); } 00411 inline TranslationPart translation() { return TranslationPart(m_matrix,0,Dim); } 00412 00437 // note: this function is defined here because some compilers cannot find the respective declaration 00438 template<typename OtherDerived> 00439 EIGEN_STRONG_INLINE const typename OtherDerived::PlainObject 00440 operator * (const EigenBase<OtherDerived> &other) const 00441 { return internal::transform_right_product_impl<Transform, OtherDerived>::run(*this,other.derived()); } 00442 00450 template<typename OtherDerived> friend 00451 inline const typename internal::transform_left_product_impl<OtherDerived,Mode,Options,_Dim,_Dim+1>::ResultType 00452 operator * (const EigenBase<OtherDerived> &a, const Transform &b) 00453 { return internal::transform_left_product_impl<OtherDerived,Mode,Options,Dim,HDim>::run(a.derived(),b); } 00454 00461 template<typename DiagonalDerived> 00462 inline const TransformTimeDiagonalReturnType 00463 operator * (const DiagonalBase<DiagonalDerived> &b) const 00464 { 00465 TransformTimeDiagonalReturnType res(*this); 00466 res.linear() *= b; 00467 return res; 00468 } 00469 00476 template<typename DiagonalDerived> 00477 friend inline TransformTimeDiagonalReturnType 00478 operator * (const DiagonalBase<DiagonalDerived> &a, const Transform &b) 00479 { 00480 TransformTimeDiagonalReturnType res; 00481 res.linear().noalias() = a*b.linear(); 00482 res.translation().noalias() = a*b.translation(); 00483 if (Mode!=int(AffineCompact)) 00484 res.matrix().row(Dim) = b.matrix().row(Dim); 00485 return res; 00486 } 00487 00488 template<typename OtherDerived> 00489 inline Transform& operator*=(const EigenBase<OtherDerived>& other) { return *this = *this * other; } 00490 00492 inline const Transform operator * (const Transform& other) const 00493 { 00494 return internal::transform_transform_product_impl<Transform,Transform>::run(*this,other); 00495 } 00496 00497 #if EIGEN_COMP_ICC 00498 private: 00499 // this intermediate structure permits to workaround a bug in ICC 11: 00500 // error: template instantiation resulted in unexpected function type of "Eigen::Transform<double, 3, 32, 0> 00501 // (const Eigen::Transform<double, 3, 2, 0> &) const" 00502 // (the meaning of a name may have changed since the template declaration -- the type of the template is: 00503 // "Eigen::internal::transform_transform_product_impl<Eigen::Transform<double, 3, 32, 0>, 00504 // Eigen::Transform<double, 3, Mode, Options>, <expression>>::ResultType (const Eigen::Transform<double, 3, Mode, Options> &) const") 00505 // 00506 template<int OtherMode,int OtherOptions> struct icc_11_workaround 00507 { 00508 typedef internal::transform_transform_product_impl<Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> > ProductType; 00509 typedef typename ProductType::ResultType ResultType; 00510 }; 00511 00512 public: 00514 template<int OtherMode,int OtherOptions> 00515 inline typename icc_11_workaround<OtherMode,OtherOptions>::ResultType 00516 operator * (const Transform<Scalar,Dim,OtherMode,OtherOptions>& other) const 00517 { 00518 typedef typename icc_11_workaround<OtherMode,OtherOptions>::ProductType ProductType; 00519 return ProductType::run(*this,other); 00520 } 00521 #else 00522 00523 template<int OtherMode,int OtherOptions> 00524 inline typename internal::transform_transform_product_impl<Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> >::ResultType 00525 operator * (const Transform<Scalar,Dim,OtherMode,OtherOptions>& other) const 00526 { 00527 return internal::transform_transform_product_impl<Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> >::run(*this,other); 00528 } 00529 #endif 00530 00532 void setIdentity() { m_matrix.setIdentity(); } 00533 00538 static const Transform Identity() 00539 { 00540 return Transform(MatrixType::Identity()); 00541 } 00542 00543 template<typename OtherDerived> 00544 inline Transform& scale(const MatrixBase<OtherDerived> &other); 00545 00546 template<typename OtherDerived> 00547 inline Transform& prescale(const MatrixBase<OtherDerived> &other); 00548 00549 inline Transform& scale(const Scalar& s); 00550 inline Transform& prescale(const Scalar& s); 00551 00552 template<typename OtherDerived> 00553 inline Transform& translate(const MatrixBase<OtherDerived> &other); 00554 00555 template<typename OtherDerived> 00556 inline Transform& pretranslate(const MatrixBase<OtherDerived> &other); 00557 00558 template<typename RotationType> 00559 inline Transform& rotate(const RotationType& rotation); 00560 00561 template<typename RotationType> 00562 inline Transform& prerotate(const RotationType& rotation); 00563 00564 Transform& shear(const Scalar& sx, const Scalar& sy); 00565 Transform& preshear(const Scalar& sx, const Scalar& sy); 00566 00567 inline Transform& operator=(const TranslationType& t); 00568 inline Transform& operator*=(const TranslationType& t) { return translate(t.vector()); } 00569 inline Transform operator*(const TranslationType& t) const; 00570 00571 inline Transform& operator=(const UniformScaling<Scalar>& t); 00572 inline Transform& operator*=(const UniformScaling<Scalar>& s) { return scale(s.factor()); } 00573 inline TransformTimeDiagonalReturnType operator*(const UniformScaling<Scalar>& s) const 00574 { 00575 TransformTimeDiagonalReturnType res = *this; 00576 res.scale(s.factor()); 00577 return res; 00578 } 00579 00580 inline Transform& operator*=(const DiagonalMatrix<Scalar,Dim>& s) { linear() *= s; return *this; } 00581 00582 template<typename Derived> 00583 inline Transform& operator=(const RotationBase<Derived,Dim>& r); 00584 template<typename Derived> 00585 inline Transform& operator*=(const RotationBase<Derived,Dim>& r) { return rotate(r.toRotationMatrix()); } 00586 template<typename Derived> 00587 inline Transform operator*(const RotationBase<Derived,Dim>& r) const; 00588 00589 const LinearMatrixType rotation() const; 00590 template<typename RotationMatrixType, typename ScalingMatrixType> 00591 void computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const; 00592 template<typename ScalingMatrixType, typename RotationMatrixType> 00593 void computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const; 00594 00595 template<typename PositionDerived, typename OrientationType, typename ScaleDerived> 00596 Transform& fromPositionOrientationScale(const MatrixBase<PositionDerived> &position, 00597 const OrientationType& orientation, const MatrixBase<ScaleDerived> &scale); 00598 00599 inline Transform inverse(TransformTraits traits = (TransformTraits)Mode) const; 00600 00602 const Scalar* data() const { return m_matrix.data(); } 00604 Scalar* data() { return m_matrix.data(); } 00605 00611 template<typename NewScalarType> 00612 inline typename internal::cast_return_type<Transform,Transform<NewScalarType,Dim,Mode,Options> >::type cast() const 00613 { return typename internal::cast_return_type<Transform,Transform<NewScalarType,Dim,Mode,Options> >::type(*this); } 00614 00616 template<typename OtherScalarType> 00617 inline explicit Transform(const Transform<OtherScalarType,Dim,Mode,Options>& other) 00618 { 00619 check_template_params(); 00620 m_matrix = other.matrix().template cast<Scalar>(); 00621 } 00622 00627 bool isApprox(const Transform& other, const typename NumTraits<Scalar>::Real& prec = NumTraits<Scalar>::dummy_precision()) const 00628 { return m_matrix.isApprox(other.m_matrix, prec); } 00629 00632 void makeAffine() 00633 { 00634 internal::transform_make_affine<int(Mode)>::run(m_matrix); 00635 } 00636 00641 inline Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,Dim> linearExt() 00642 { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,Dim>(0,0); } 00647 inline const Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,Dim> linearExt() const 00648 { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,Dim>(0,0); } 00649 00654 inline Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,1> translationExt() 00655 { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,1>(0,Dim); } 00660 inline const Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,1> translationExt() const 00661 { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,1>(0,Dim); } 00662 00663 00664 #ifdef EIGEN_TRANSFORM_PLUGIN 00665 #include EIGEN_TRANSFORM_PLUGIN 00666 #endif 00667 00668 protected: 00669 #ifndef EIGEN_PARSED_BY_DOXYGEN 00670 static EIGEN_STRONG_INLINE void check_template_params() 00671 { 00672 EIGEN_STATIC_ASSERT((Options & (DontAlign|RowMajor)) == Options, INVALID_MATRIX_TEMPLATE_PARAMETERS) 00673 } 00674 #endif 00675 00676 }; 00677 00679 typedef Transform<float,2,Isometry> Isometry2f; 00681 typedef Transform<float,3,Isometry> Isometry3f; 00683 typedef Transform<double,2,Isometry> Isometry2d; 00685 typedef Transform<double,3,Isometry> Isometry3d; 00686 00688 typedef Transform<float,2,Affine> Affine2f; 00690 typedef Transform<float,3,Affine> Affine3f; 00692 typedef Transform<double,2,Affine> Affine2d; 00694 typedef Transform<double,3,Affine> Affine3d; 00695 00697 typedef Transform<float,2,AffineCompact> AffineCompact2f; 00699 typedef Transform<float,3,AffineCompact> AffineCompact3f; 00701 typedef Transform<double,2,AffineCompact> AffineCompact2d; 00703 typedef Transform<double,3,AffineCompact> AffineCompact3d; 00704 00706 typedef Transform<float,2,Projective> Projective2f; 00708 typedef Transform<float,3,Projective> Projective3f; 00710 typedef Transform<double,2,Projective> Projective2d; 00712 typedef Transform<double,3,Projective> Projective3d; 00713 00714 /************************** 00715 *** Optional QT support *** 00716 **************************/ 00717 00718 #ifdef EIGEN_QT_SUPPORT 00719 00723 template<typename Scalar, int Dim, int Mode,int Options> 00724 Transform<Scalar,Dim,Mode,Options>::Transform(const QMatrix& other) 00725 { 00726 check_template_params(); 00727 *this = other; 00728 } 00729 00734 template<typename Scalar, int Dim, int Mode,int Options> 00735 Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const QMatrix& other) 00736 { 00737 EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE) 00738 if (Mode == int(AffineCompact)) 00739 m_matrix << other.m11(), other.m21(), other.dx(), 00740 other.m12(), other.m22(), other.dy(); 00741 else 00742 m_matrix << other.m11(), other.m21(), other.dx(), 00743 other.m12(), other.m22(), other.dy(), 00744 0, 0, 1; 00745 return *this; 00746 } 00747 00754 template<typename Scalar, int Dim, int Mode, int Options> 00755 QMatrix Transform<Scalar,Dim,Mode,Options>::toQMatrix(void) const 00756 { 00757 check_template_params(); 00758 EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE) 00759 return QMatrix(m_matrix.coeff(0,0), m_matrix.coeff(1,0), 00760 m_matrix.coeff(0,1), m_matrix.coeff(1,1), 00761 m_matrix.coeff(0,2), m_matrix.coeff(1,2)); 00762 } 00763 00768 template<typename Scalar, int Dim, int Mode,int Options> 00769 Transform<Scalar,Dim,Mode,Options>::Transform(const QTransform& other) 00770 { 00771 check_template_params(); 00772 *this = other; 00773 } 00774 00779 template<typename Scalar, int Dim, int Mode, int Options> 00780 Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const QTransform& other) 00781 { 00782 check_template_params(); 00783 EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE) 00784 if (Mode == int(AffineCompact)) 00785 m_matrix << other.m11(), other.m21(), other.dx(), 00786 other.m12(), other.m22(), other.dy(); 00787 else 00788 m_matrix << other.m11(), other.m21(), other.dx(), 00789 other.m12(), other.m22(), other.dy(), 00790 other.m13(), other.m23(), other.m33(); 00791 return *this; 00792 } 00793 00798 template<typename Scalar, int Dim, int Mode, int Options> 00799 QTransform Transform<Scalar,Dim,Mode,Options>::toQTransform(void) const 00800 { 00801 EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE) 00802 if (Mode == int(AffineCompact)) 00803 return QTransform(m_matrix.coeff(0,0), m_matrix.coeff(1,0), 00804 m_matrix.coeff(0,1), m_matrix.coeff(1,1), 00805 m_matrix.coeff(0,2), m_matrix.coeff(1,2)); 00806 else 00807 return QTransform(m_matrix.coeff(0,0), m_matrix.coeff(1,0), m_matrix.coeff(2,0), 00808 m_matrix.coeff(0,1), m_matrix.coeff(1,1), m_matrix.coeff(2,1), 00809 m_matrix.coeff(0,2), m_matrix.coeff(1,2), m_matrix.coeff(2,2)); 00810 } 00811 #endif 00812 00813 /********************* 00814 *** Procedural API *** 00815 *********************/ 00816 00821 template<typename Scalar, int Dim, int Mode, int Options> 00822 template<typename OtherDerived> 00823 Transform<Scalar,Dim,Mode,Options>& 00824 Transform<Scalar,Dim,Mode,Options>::scale(const MatrixBase<OtherDerived> &other) 00825 { 00826 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) 00827 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) 00828 linearExt().noalias() = (linearExt() * other.asDiagonal()); 00829 return *this; 00830 } 00831 00836 template<typename Scalar, int Dim, int Mode, int Options> 00837 inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::scale(const Scalar& s) 00838 { 00839 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) 00840 linearExt() *= s; 00841 return *this; 00842 } 00843 00848 template<typename Scalar, int Dim, int Mode, int Options> 00849 template<typename OtherDerived> 00850 Transform<Scalar,Dim,Mode,Options>& 00851 Transform<Scalar,Dim,Mode,Options>::prescale(const MatrixBase<OtherDerived> &other) 00852 { 00853 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) 00854 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) 00855 m_matrix.template block<Dim,HDim>(0,0).noalias() = (other.asDiagonal() * m_matrix.template block<Dim,HDim>(0,0)); 00856 return *this; 00857 } 00858 00863 template<typename Scalar, int Dim, int Mode, int Options> 00864 inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::prescale(const Scalar& s) 00865 { 00866 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) 00867 m_matrix.template topRows<Dim>() *= s; 00868 return *this; 00869 } 00870 00875 template<typename Scalar, int Dim, int Mode, int Options> 00876 template<typename OtherDerived> 00877 Transform<Scalar,Dim,Mode,Options>& 00878 Transform<Scalar,Dim,Mode,Options>::translate(const MatrixBase<OtherDerived> &other) 00879 { 00880 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) 00881 translationExt() += linearExt() * other; 00882 return *this; 00883 } 00884 00889 template<typename Scalar, int Dim, int Mode, int Options> 00890 template<typename OtherDerived> 00891 Transform<Scalar,Dim,Mode,Options>& 00892 Transform<Scalar,Dim,Mode,Options>::pretranslate(const MatrixBase<OtherDerived> &other) 00893 { 00894 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) 00895 if(int(Mode)==int(Projective)) 00896 affine() += other * m_matrix.row(Dim); 00897 else 00898 translation() += other; 00899 return *this; 00900 } 00901 00919 template<typename Scalar, int Dim, int Mode, int Options> 00920 template<typename RotationType> 00921 Transform<Scalar,Dim,Mode,Options>& 00922 Transform<Scalar,Dim,Mode,Options>::rotate(const RotationType& rotation) 00923 { 00924 linearExt() *= internal::toRotationMatrix<Scalar,Dim>(rotation); 00925 return *this; 00926 } 00927 00935 template<typename Scalar, int Dim, int Mode, int Options> 00936 template<typename RotationType> 00937 Transform<Scalar,Dim,Mode,Options>& 00938 Transform<Scalar,Dim,Mode,Options>::prerotate(const RotationType& rotation) 00939 { 00940 m_matrix.template block<Dim,HDim>(0,0) = internal::toRotationMatrix<Scalar,Dim>(rotation) 00941 * m_matrix.template block<Dim,HDim>(0,0); 00942 return *this; 00943 } 00944 00950 template<typename Scalar, int Dim, int Mode, int Options> 00951 Transform<Scalar,Dim,Mode,Options>& 00952 Transform<Scalar,Dim,Mode,Options>::shear(const Scalar& sx, const Scalar& sy) 00953 { 00954 EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE) 00955 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) 00956 VectorType tmp = linear().col(0)*sy + linear().col(1); 00957 linear() << linear().col(0) + linear().col(1)*sx, tmp; 00958 return *this; 00959 } 00960 00966 template<typename Scalar, int Dim, int Mode, int Options> 00967 Transform<Scalar,Dim,Mode,Options>& 00968 Transform<Scalar,Dim,Mode,Options>::preshear(const Scalar& sx, const Scalar& sy) 00969 { 00970 EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE) 00971 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) 00972 m_matrix.template block<Dim,HDim>(0,0) = LinearMatrixType(1, sx, sy, 1) * m_matrix.template block<Dim,HDim>(0,0); 00973 return *this; 00974 } 00975 00976 /****************************************************** 00977 *** Scaling, Translation and Rotation compatibility *** 00978 ******************************************************/ 00979 00980 template<typename Scalar, int Dim, int Mode, int Options> 00981 inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const TranslationType& t) 00982 { 00983 linear().setIdentity(); 00984 translation() = t.vector(); 00985 makeAffine(); 00986 return *this; 00987 } 00988 00989 template<typename Scalar, int Dim, int Mode, int Options> 00990 inline Transform<Scalar,Dim,Mode,Options> Transform<Scalar,Dim,Mode,Options>::operator*(const TranslationType& t) const 00991 { 00992 Transform res = *this; 00993 res.translate(t.vector()); 00994 return res; 00995 } 00996 00997 template<typename Scalar, int Dim, int Mode, int Options> 00998 inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const UniformScaling<Scalar>& s) 00999 { 01000 m_matrix.setZero(); 01001 linear().diagonal().fill(s.factor()); 01002 makeAffine(); 01003 return *this; 01004 } 01005 01006 template<typename Scalar, int Dim, int Mode, int Options> 01007 template<typename Derived> 01008 inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const RotationBase<Derived,Dim>& r) 01009 { 01010 linear() = internal::toRotationMatrix<Scalar,Dim>(r); 01011 translation().setZero(); 01012 makeAffine(); 01013 return *this; 01014 } 01015 01016 template<typename Scalar, int Dim, int Mode, int Options> 01017 template<typename Derived> 01018 inline Transform<Scalar,Dim,Mode,Options> Transform<Scalar,Dim,Mode,Options>::operator*(const RotationBase<Derived,Dim>& r) const 01019 { 01020 Transform res = *this; 01021 res.rotate(r.derived()); 01022 return res; 01023 } 01024 01025 /************************ 01026 *** Special functions *** 01027 ************************/ 01028 01036 template<typename Scalar, int Dim, int Mode, int Options> 01037 const typename Transform<Scalar,Dim,Mode,Options>::LinearMatrixType 01038 Transform<Scalar,Dim,Mode,Options>::rotation() const 01039 { 01040 LinearMatrixType result; 01041 computeRotationScaling(&result, (LinearMatrixType*)0); 01042 return result; 01043 } 01044 01045 01057 template<typename Scalar, int Dim, int Mode, int Options> 01058 template<typename RotationMatrixType, typename ScalingMatrixType> 01059 void Transform<Scalar,Dim,Mode,Options>::computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const 01060 { 01061 JacobiSVD<LinearMatrixType> svd(linear(), ComputeFullU | ComputeFullV); 01062 01063 Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant(); // so x has absolute value 1 01064 VectorType sv(svd.singularValues()); 01065 sv.coeffRef(0) *= x; 01066 if(scaling) scaling->lazyAssign(svd.matrixV() * sv.asDiagonal() * svd.matrixV().adjoint()); 01067 if(rotation) 01068 { 01069 LinearMatrixType m(svd.matrixU()); 01070 m.col(0) /= x; 01071 rotation->lazyAssign(m * svd.matrixV().adjoint()); 01072 } 01073 } 01074 01086 template<typename Scalar, int Dim, int Mode, int Options> 01087 template<typename ScalingMatrixType, typename RotationMatrixType> 01088 void Transform<Scalar,Dim,Mode,Options>::computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const 01089 { 01090 JacobiSVD<LinearMatrixType> svd(linear(), ComputeFullU | ComputeFullV); 01091 01092 Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant(); // so x has absolute value 1 01093 VectorType sv(svd.singularValues()); 01094 sv.coeffRef(0) *= x; 01095 if(scaling) scaling->lazyAssign(svd.matrixU() * sv.asDiagonal() * svd.matrixU().adjoint()); 01096 if(rotation) 01097 { 01098 LinearMatrixType m(svd.matrixU()); 01099 m.col(0) /= x; 01100 rotation->lazyAssign(m * svd.matrixV().adjoint()); 01101 } 01102 } 01103 01107 template<typename Scalar, int Dim, int Mode, int Options> 01108 template<typename PositionDerived, typename OrientationType, typename ScaleDerived> 01109 Transform<Scalar,Dim,Mode,Options>& 01110 Transform<Scalar,Dim,Mode,Options>::fromPositionOrientationScale(const MatrixBase<PositionDerived> &position, 01111 const OrientationType& orientation, const MatrixBase<ScaleDerived> &scale) 01112 { 01113 linear() = internal::toRotationMatrix<Scalar,Dim>(orientation); 01114 linear() *= scale.asDiagonal(); 01115 translation() = position; 01116 makeAffine(); 01117 return *this; 01118 } 01119 01120 namespace internal { 01121 01122 template<int Mode> 01123 struct transform_make_affine 01124 { 01125 template<typename MatrixType> 01126 static void run(MatrixType &mat) 01127 { 01128 static const int Dim = MatrixType::ColsAtCompileTime-1; 01129 mat.template block<1,Dim>(Dim,0).setZero(); 01130 mat.coeffRef(Dim,Dim) = typename MatrixType::Scalar(1); 01131 } 01132 }; 01133 01134 template<> 01135 struct transform_make_affine<AffineCompact> 01136 { 01137 template<typename MatrixType> static void run(MatrixType &) { } 01138 }; 01139 01140 // selector needed to avoid taking the inverse of a 3x4 matrix 01141 template<typename TransformType, int Mode=TransformType::Mode> 01142 struct projective_transform_inverse 01143 { 01144 static inline void run(const TransformType&, TransformType&) 01145 {} 01146 }; 01147 01148 template<typename TransformType> 01149 struct projective_transform_inverse<TransformType, Projective> 01150 { 01151 static inline void run(const TransformType& m, TransformType& res) 01152 { 01153 res.matrix() = m.matrix().inverse(); 01154 } 01155 }; 01156 01157 } // end namespace internal 01158 01159 01180 template<typename Scalar, int Dim, int Mode, int Options> 01181 Transform<Scalar,Dim,Mode,Options> 01182 Transform<Scalar,Dim,Mode,Options>::inverse(TransformTraits hint) const 01183 { 01184 Transform res; 01185 if (hint == Projective) 01186 { 01187 internal::projective_transform_inverse<Transform>::run(*this, res); 01188 } 01189 else 01190 { 01191 if (hint == Isometry) 01192 { 01193 res.matrix().template topLeftCorner<Dim,Dim>() = linear().transpose(); 01194 } 01195 else if(hint&Affine) 01196 { 01197 res.matrix().template topLeftCorner<Dim,Dim>() = linear().inverse(); 01198 } 01199 else 01200 { 01201 eigen_assert(false && "Invalid transform traits in Transform::Inverse"); 01202 } 01203 // translation and remaining parts 01204 res.matrix().template topRightCorner<Dim,1>() 01205 = - res.matrix().template topLeftCorner<Dim,Dim>() * translation(); 01206 res.makeAffine(); // we do need this, because in the beginning res is uninitialized 01207 } 01208 return res; 01209 } 01210 01211 namespace internal { 01212 01213 /***************************************************** 01214 *** Specializations of take affine part *** 01215 *****************************************************/ 01216 01217 template<typename TransformType> struct transform_take_affine_part { 01218 typedef typename TransformType::MatrixType MatrixType; 01219 typedef typename TransformType::AffinePart AffinePart; 01220 typedef typename TransformType::ConstAffinePart ConstAffinePart; 01221 static inline AffinePart run(MatrixType& m) 01222 { return m.template block<TransformType::Dim,TransformType::HDim>(0,0); } 01223 static inline ConstAffinePart run(const MatrixType& m) 01224 { return m.template block<TransformType::Dim,TransformType::HDim>(0,0); } 01225 }; 01226 01227 template<typename Scalar, int Dim, int Options> 01228 struct transform_take_affine_part<Transform<Scalar,Dim,AffineCompact, Options> > { 01229 typedef typename Transform<Scalar,Dim,AffineCompact,Options>::MatrixType MatrixType; 01230 static inline MatrixType& run(MatrixType& m) { return m; } 01231 static inline const MatrixType& run(const MatrixType& m) { return m; } 01232 }; 01233 01234 /***************************************************** 01235 *** Specializations of construct from matrix *** 01236 *****************************************************/ 01237 01238 template<typename Other, int Mode, int Options, int Dim, int HDim> 01239 struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, Dim,Dim> 01240 { 01241 static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other) 01242 { 01243 transform->linear() = other; 01244 transform->translation().setZero(); 01245 transform->makeAffine(); 01246 } 01247 }; 01248 01249 template<typename Other, int Mode, int Options, int Dim, int HDim> 01250 struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, Dim,HDim> 01251 { 01252 static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other) 01253 { 01254 transform->affine() = other; 01255 transform->makeAffine(); 01256 } 01257 }; 01258 01259 template<typename Other, int Mode, int Options, int Dim, int HDim> 01260 struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, HDim,HDim> 01261 { 01262 static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other) 01263 { transform->matrix() = other; } 01264 }; 01265 01266 template<typename Other, int Options, int Dim, int HDim> 01267 struct transform_construct_from_matrix<Other, AffineCompact,Options,Dim,HDim, HDim,HDim> 01268 { 01269 static inline void run(Transform<typename Other::Scalar,Dim,AffineCompact,Options> *transform, const Other& other) 01270 { transform->matrix() = other.template block<Dim,HDim>(0,0); } 01271 }; 01272 01273 /********************************************************** 01274 *** Specializations of operator* with rhs EigenBase *** 01275 **********************************************************/ 01276 01277 template<int LhsMode,int RhsMode> 01278 struct transform_product_result 01279 { 01280 enum 01281 { 01282 Mode = 01283 (LhsMode == (int)Projective || RhsMode == (int)Projective ) ? Projective : 01284 (LhsMode == (int)Affine || RhsMode == (int)Affine ) ? Affine : 01285 (LhsMode == (int)AffineCompact || RhsMode == (int)AffineCompact ) ? AffineCompact : 01286 (LhsMode == (int)Isometry || RhsMode == (int)Isometry ) ? Isometry : Projective 01287 }; 01288 }; 01289 01290 template< typename TransformType, typename MatrixType > 01291 struct transform_right_product_impl< TransformType, MatrixType, 0 > 01292 { 01293 typedef typename MatrixType::PlainObject ResultType; 01294 01295 static EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other) 01296 { 01297 return T.matrix() * other; 01298 } 01299 }; 01300 01301 template< typename TransformType, typename MatrixType > 01302 struct transform_right_product_impl< TransformType, MatrixType, 1 > 01303 { 01304 enum { 01305 Dim = TransformType::Dim, 01306 HDim = TransformType::HDim, 01307 OtherRows = MatrixType::RowsAtCompileTime, 01308 OtherCols = MatrixType::ColsAtCompileTime 01309 }; 01310 01311 typedef typename MatrixType::PlainObject ResultType; 01312 01313 static EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other) 01314 { 01315 EIGEN_STATIC_ASSERT(OtherRows==HDim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES); 01316 01317 typedef Block<ResultType, Dim, OtherCols, int(MatrixType::RowsAtCompileTime)==Dim> TopLeftLhs; 01318 01319 ResultType res(other.rows(),other.cols()); 01320 TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() = T.affine() * other; 01321 res.row(OtherRows-1) = other.row(OtherRows-1); 01322 01323 return res; 01324 } 01325 }; 01326 01327 template< typename TransformType, typename MatrixType > 01328 struct transform_right_product_impl< TransformType, MatrixType, 2 > 01329 { 01330 enum { 01331 Dim = TransformType::Dim, 01332 HDim = TransformType::HDim, 01333 OtherRows = MatrixType::RowsAtCompileTime, 01334 OtherCols = MatrixType::ColsAtCompileTime 01335 }; 01336 01337 typedef typename MatrixType::PlainObject ResultType; 01338 01339 static EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other) 01340 { 01341 EIGEN_STATIC_ASSERT(OtherRows==Dim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES); 01342 01343 typedef Block<ResultType, Dim, OtherCols, true> TopLeftLhs; 01344 ResultType res(Replicate<typename TransformType::ConstTranslationPart, 1, OtherCols>(T.translation(),1,other.cols())); 01345 TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() += T.linear() * other; 01346 01347 return res; 01348 } 01349 }; 01350 01351 /********************************************************** 01352 *** Specializations of operator* with lhs EigenBase *** 01353 **********************************************************/ 01354 01355 // generic HDim x HDim matrix * T => Projective 01356 template<typename Other,int Mode, int Options, int Dim, int HDim> 01357 struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, HDim,HDim> 01358 { 01359 typedef Transform<typename Other::Scalar,Dim,Mode,Options> TransformType; 01360 typedef typename TransformType::MatrixType MatrixType; 01361 typedef Transform<typename Other::Scalar,Dim,Projective,Options> ResultType; 01362 static ResultType run(const Other& other,const TransformType& tr) 01363 { return ResultType(other * tr.matrix()); } 01364 }; 01365 01366 // generic HDim x HDim matrix * AffineCompact => Projective 01367 template<typename Other, int Options, int Dim, int HDim> 01368 struct transform_left_product_impl<Other,AffineCompact,Options,Dim,HDim, HDim,HDim> 01369 { 01370 typedef Transform<typename Other::Scalar,Dim,AffineCompact,Options> TransformType; 01371 typedef typename TransformType::MatrixType MatrixType; 01372 typedef Transform<typename Other::Scalar,Dim,Projective,Options> ResultType; 01373 static ResultType run(const Other& other,const TransformType& tr) 01374 { 01375 ResultType res; 01376 res.matrix().noalias() = other.template block<HDim,Dim>(0,0) * tr.matrix(); 01377 res.matrix().col(Dim) += other.col(Dim); 01378 return res; 01379 } 01380 }; 01381 01382 // affine matrix * T 01383 template<typename Other,int Mode, int Options, int Dim, int HDim> 01384 struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, Dim,HDim> 01385 { 01386 typedef Transform<typename Other::Scalar,Dim,Mode,Options> TransformType; 01387 typedef typename TransformType::MatrixType MatrixType; 01388 typedef TransformType ResultType; 01389 static ResultType run(const Other& other,const TransformType& tr) 01390 { 01391 ResultType res; 01392 res.affine().noalias() = other * tr.matrix(); 01393 res.matrix().row(Dim) = tr.matrix().row(Dim); 01394 return res; 01395 } 01396 }; 01397 01398 // affine matrix * AffineCompact 01399 template<typename Other, int Options, int Dim, int HDim> 01400 struct transform_left_product_impl<Other,AffineCompact,Options,Dim,HDim, Dim,HDim> 01401 { 01402 typedef Transform<typename Other::Scalar,Dim,AffineCompact,Options> TransformType; 01403 typedef typename TransformType::MatrixType MatrixType; 01404 typedef TransformType ResultType; 01405 static ResultType run(const Other& other,const TransformType& tr) 01406 { 01407 ResultType res; 01408 res.matrix().noalias() = other.template block<Dim,Dim>(0,0) * tr.matrix(); 01409 res.translation() += other.col(Dim); 01410 return res; 01411 } 01412 }; 01413 01414 // linear matrix * T 01415 template<typename Other,int Mode, int Options, int Dim, int HDim> 01416 struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, Dim,Dim> 01417 { 01418 typedef Transform<typename Other::Scalar,Dim,Mode,Options> TransformType; 01419 typedef typename TransformType::MatrixType MatrixType; 01420 typedef TransformType ResultType; 01421 static ResultType run(const Other& other, const TransformType& tr) 01422 { 01423 TransformType res; 01424 if(Mode!=int(AffineCompact)) 01425 res.matrix().row(Dim) = tr.matrix().row(Dim); 01426 res.matrix().template topRows<Dim>().noalias() 01427 = other * tr.matrix().template topRows<Dim>(); 01428 return res; 01429 } 01430 }; 01431 01432 /********************************************************** 01433 *** Specializations of operator* with another Transform *** 01434 **********************************************************/ 01435 01436 template<typename Scalar, int Dim, int LhsMode, int LhsOptions, int RhsMode, int RhsOptions> 01437 struct transform_transform_product_impl<Transform<Scalar,Dim,LhsMode,LhsOptions>,Transform<Scalar,Dim,RhsMode,RhsOptions>,false > 01438 { 01439 enum { ResultMode = transform_product_result<LhsMode,RhsMode>::Mode }; 01440 typedef Transform<Scalar,Dim,LhsMode,LhsOptions> Lhs; 01441 typedef Transform<Scalar,Dim,RhsMode,RhsOptions> Rhs; 01442 typedef Transform<Scalar,Dim,ResultMode,LhsOptions> ResultType; 01443 static ResultType run(const Lhs& lhs, const Rhs& rhs) 01444 { 01445 ResultType res; 01446 res.linear() = lhs.linear() * rhs.linear(); 01447 res.translation() = lhs.linear() * rhs.translation() + lhs.translation(); 01448 res.makeAffine(); 01449 return res; 01450 } 01451 }; 01452 01453 template<typename Scalar, int Dim, int LhsMode, int LhsOptions, int RhsMode, int RhsOptions> 01454 struct transform_transform_product_impl<Transform<Scalar,Dim,LhsMode,LhsOptions>,Transform<Scalar,Dim,RhsMode,RhsOptions>,true > 01455 { 01456 typedef Transform<Scalar,Dim,LhsMode,LhsOptions> Lhs; 01457 typedef Transform<Scalar,Dim,RhsMode,RhsOptions> Rhs; 01458 typedef Transform<Scalar,Dim,Projective> ResultType; 01459 static ResultType run(const Lhs& lhs, const Rhs& rhs) 01460 { 01461 return ResultType( lhs.matrix() * rhs.matrix() ); 01462 } 01463 }; 01464 01465 template<typename Scalar, int Dim, int LhsOptions, int RhsOptions> 01466 struct transform_transform_product_impl<Transform<Scalar,Dim,AffineCompact,LhsOptions>,Transform<Scalar,Dim,Projective,RhsOptions>,true > 01467 { 01468 typedef Transform<Scalar,Dim,AffineCompact,LhsOptions> Lhs; 01469 typedef Transform<Scalar,Dim,Projective,RhsOptions> Rhs; 01470 typedef Transform<Scalar,Dim,Projective> ResultType; 01471 static ResultType run(const Lhs& lhs, const Rhs& rhs) 01472 { 01473 ResultType res; 01474 res.matrix().template topRows<Dim>() = lhs.matrix() * rhs.matrix(); 01475 res.matrix().row(Dim) = rhs.matrix().row(Dim); 01476 return res; 01477 } 01478 }; 01479 01480 template<typename Scalar, int Dim, int LhsOptions, int RhsOptions> 01481 struct transform_transform_product_impl<Transform<Scalar,Dim,Projective,LhsOptions>,Transform<Scalar,Dim,AffineCompact,RhsOptions>,true > 01482 { 01483 typedef Transform<Scalar,Dim,Projective,LhsOptions> Lhs; 01484 typedef Transform<Scalar,Dim,AffineCompact,RhsOptions> Rhs; 01485 typedef Transform<Scalar,Dim,Projective> ResultType; 01486 static ResultType run(const Lhs& lhs, const Rhs& rhs) 01487 { 01488 ResultType res(lhs.matrix().template leftCols<Dim>() * rhs.matrix()); 01489 res.matrix().col(Dim) += lhs.matrix().col(Dim); 01490 return res; 01491 } 01492 }; 01493 01494 } // end namespace internal 01495 01496 } // end namespace Eigen 01497 01498 #endif // EIGEN_TRANSFORM_H