![]() |
Eigen
3.3.3
|
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> 00005 // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com> 00006 // Copyright (C) 2010 Hauke Heibel <hauke.heibel@gmail.com> 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 int RhsCols = MatrixType::ColsAtCompileTime> 00037 struct transform_right_product_impl; 00038 00039 template< typename Other, 00040 int Mode, 00041 int Options, 00042 int Dim, 00043 int HDim, 00044 int OtherRows=Other::RowsAtCompileTime, 00045 int OtherCols=Other::ColsAtCompileTime> 00046 struct transform_left_product_impl; 00047 00048 template< typename Lhs, 00049 typename Rhs, 00050 bool AnyProjective = 00051 transform_traits<Lhs>::IsProjective || 00052 transform_traits<Rhs>::IsProjective> 00053 struct transform_transform_product_impl; 00054 00055 template< typename Other, 00056 int Mode, 00057 int Options, 00058 int Dim, 00059 int HDim, 00060 int OtherRows=Other::RowsAtCompileTime, 00061 int OtherCols=Other::ColsAtCompileTime> 00062 struct transform_construct_from_matrix; 00063 00064 template<typename TransformType> struct transform_take_affine_part; 00065 00066 template<typename _Scalar, int _Dim, int _Mode, int _Options> 00067 struct traits<Transform<_Scalar,_Dim,_Mode,_Options> > 00068 { 00069 typedef _Scalar Scalar; 00070 typedef Eigen::Index StorageIndex; 00071 typedef Dense StorageKind; 00072 enum { 00073 Dim1 = _Dim==Dynamic ? _Dim : _Dim + 1, 00074 RowsAtCompileTime = _Mode==Projective ? Dim1 : _Dim, 00075 ColsAtCompileTime = Dim1, 00076 MaxRowsAtCompileTime = RowsAtCompileTime, 00077 MaxColsAtCompileTime = ColsAtCompileTime, 00078 Flags = 0 00079 }; 00080 }; 00081 00082 template<int Mode> struct transform_make_affine; 00083 00084 } // end namespace internal 00085 00200 template<typename _Scalar, int _Dim, int _Mode, int _Options> 00201 class Transform 00202 { 00203 public: 00204 EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_Dim==Dynamic ? Dynamic : (_Dim+1)*(_Dim+1)) 00205 enum { 00206 Mode = _Mode, 00207 Options = _Options, 00208 Dim = _Dim, 00209 HDim = _Dim+1, 00210 Rows = int(Mode)==(AffineCompact) ? Dim : HDim 00211 }; 00213 typedef _Scalar Scalar; 00214 typedef Eigen::Index StorageIndex; 00215 typedef Eigen::Index Index; 00216 00217 typedef typename internal::make_proper_matrix_type<Scalar,Rows,HDim,Options>::type MatrixType; 00219 typedef const MatrixType ConstMatrixType; 00221 typedef Matrix<Scalar,Dim,Dim,Options> LinearMatrixType; 00223 typedef Block<MatrixType,Dim,Dim,int(Mode)==(AffineCompact) && (Options&RowMajor)==0> LinearPart; 00225 typedef const Block<ConstMatrixType,Dim,Dim,int(Mode)==(AffineCompact) && (Options&RowMajor)==0> ConstLinearPart; 00227 typedef typename internal::conditional<int(Mode)==int(AffineCompact), 00228 MatrixType&, 00229 Block<MatrixType,Dim,HDim> >::type AffinePart; 00231 typedef typename internal::conditional<int(Mode)==int(AffineCompact), 00232 const MatrixType&, 00233 const Block<const MatrixType,Dim,HDim> >::type ConstAffinePart; 00235 typedef Matrix<Scalar,Dim,1> VectorType; 00237 typedef Block<MatrixType,Dim,1,!(internal::traits<MatrixType>::Flags & RowMajorBit)> TranslationPart; 00239 typedef const Block<ConstMatrixType,Dim,1,!(internal::traits<MatrixType>::Flags & RowMajorBit)> ConstTranslationPart; 00241 typedef Translation<Scalar,Dim> TranslationType; 00242 00243 // this intermediate enum is needed to avoid an ICE with gcc 3.4 and 4.0 00244 enum { TransformTimeDiagonalMode = ((Mode==int(Isometry))?Affine:int(Mode)) }; 00246 typedef Transform<Scalar,Dim,TransformTimeDiagonalMode> TransformTimeDiagonalReturnType; 00247 00248 protected: 00249 00250 MatrixType m_matrix; 00251 00252 public: 00253 00256 EIGEN_DEVICE_FUNC inline Transform() 00257 { 00258 check_template_params(); 00259 internal::transform_make_affine<(int(Mode)==Affine) ? Affine : AffineCompact>::run(m_matrix); 00260 } 00261 00262 EIGEN_DEVICE_FUNC inline Transform(const Transform& other) 00263 { 00264 check_template_params(); 00265 m_matrix = other.m_matrix; 00266 } 00267 00268 EIGEN_DEVICE_FUNC inline explicit Transform(const TranslationType& t) 00269 { 00270 check_template_params(); 00271 *this = t; 00272 } 00273 EIGEN_DEVICE_FUNC inline explicit Transform(const UniformScaling<Scalar>& s) 00274 { 00275 check_template_params(); 00276 *this = s; 00277 } 00278 template<typename Derived> 00279 EIGEN_DEVICE_FUNC inline explicit Transform(const RotationBase<Derived, Dim>& r) 00280 { 00281 check_template_params(); 00282 *this = r; 00283 } 00284 00285 EIGEN_DEVICE_FUNC inline Transform& operator=(const Transform& other) 00286 { m_matrix = other.m_matrix; return *this; } 00287 00288 typedef internal::transform_take_affine_part<Transform> take_affine_part; 00289 00291 template<typename OtherDerived> 00292 EIGEN_DEVICE_FUNC inline explicit Transform(const EigenBase<OtherDerived>& other) 00293 { 00294 EIGEN_STATIC_ASSERT((internal::is_same<Scalar,typename OtherDerived::Scalar>::value), 00295 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY); 00296 00297 check_template_params(); 00298 internal::transform_construct_from_matrix<OtherDerived,Mode,Options,Dim,HDim>::run(this, other.derived()); 00299 } 00300 00302 template<typename OtherDerived> 00303 EIGEN_DEVICE_FUNC inline Transform& operator=(const EigenBase<OtherDerived>& other) 00304 { 00305 EIGEN_STATIC_ASSERT((internal::is_same<Scalar,typename OtherDerived::Scalar>::value), 00306 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY); 00307 00308 internal::transform_construct_from_matrix<OtherDerived,Mode,Options,Dim,HDim>::run(this, other.derived()); 00309 return *this; 00310 } 00311 00312 template<int OtherOptions> 00313 EIGEN_DEVICE_FUNC inline Transform(const Transform<Scalar,Dim,Mode,OtherOptions>& other) 00314 { 00315 check_template_params(); 00316 // only the options change, we can directly copy the matrices 00317 m_matrix = other.matrix(); 00318 } 00319 00320 template<int OtherMode,int OtherOptions> 00321 EIGEN_DEVICE_FUNC inline Transform(const Transform<Scalar,Dim,OtherMode,OtherOptions>& other) 00322 { 00323 check_template_params(); 00324 // prevent conversions as: 00325 // Affine | AffineCompact | Isometry = Projective 00326 EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(OtherMode==int(Projective), Mode==int(Projective)), 00327 YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION) 00328 00329 // prevent conversions as: 00330 // Isometry = Affine | AffineCompact 00331 EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(OtherMode==int(Affine)||OtherMode==int(AffineCompact), Mode!=int(Isometry)), 00332 YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION) 00333 00334 enum { ModeIsAffineCompact = Mode == int(AffineCompact), 00335 OtherModeIsAffineCompact = OtherMode == int(AffineCompact) 00336 }; 00337 00338 if(ModeIsAffineCompact == OtherModeIsAffineCompact) 00339 { 00340 // We need the block expression because the code is compiled for all 00341 // combinations of transformations and will trigger a compile time error 00342 // if one tries to assign the matrices directly 00343 m_matrix.template block<Dim,Dim+1>(0,0) = other.matrix().template block<Dim,Dim+1>(0,0); 00344 makeAffine(); 00345 } 00346 else if(OtherModeIsAffineCompact) 00347 { 00348 typedef typename Transform<Scalar,Dim,OtherMode,OtherOptions>::MatrixType OtherMatrixType; 00349 internal::transform_construct_from_matrix<OtherMatrixType,Mode,Options,Dim,HDim>::run(this, other.matrix()); 00350 } 00351 else 00352 { 00353 // here we know that Mode == AffineCompact and OtherMode != AffineCompact. 00354 // if OtherMode were Projective, the static assert above would already have caught it. 00355 // So the only possibility is that OtherMode == Affine 00356 linear() = other.linear(); 00357 translation() = other.translation(); 00358 } 00359 } 00360 00361 template<typename OtherDerived> 00362 EIGEN_DEVICE_FUNC Transform(const ReturnByValue<OtherDerived>& other) 00363 { 00364 check_template_params(); 00365 other.evalTo(*this); 00366 } 00367 00368 template<typename OtherDerived> 00369 EIGEN_DEVICE_FUNC Transform& operator=(const ReturnByValue<OtherDerived>& other) 00370 { 00371 other.evalTo(*this); 00372 return *this; 00373 } 00374 00375 #ifdef EIGEN_QT_SUPPORT 00376 inline Transform(const QMatrix& other); 00377 inline Transform& operator=(const QMatrix& other); 00378 inline QMatrix toQMatrix(void) const; 00379 inline Transform(const QTransform& other); 00380 inline Transform& operator=(const QTransform& other); 00381 inline QTransform toQTransform(void) const; 00382 #endif 00383 00384 EIGEN_DEVICE_FUNC Index rows() const { return int(Mode)==int(Projective) ? m_matrix.cols() : (m_matrix.cols()-1); } 00385 EIGEN_DEVICE_FUNC Index cols() const { return m_matrix.cols(); } 00386 00389 EIGEN_DEVICE_FUNC inline Scalar operator() (Index row, Index col) const { return m_matrix(row,col); } 00392 EIGEN_DEVICE_FUNC inline Scalar& operator() (Index row, Index col) { return m_matrix(row,col); } 00393 00395 EIGEN_DEVICE_FUNC inline const MatrixType& matrix() const { return m_matrix; } 00397 EIGEN_DEVICE_FUNC inline MatrixType& matrix() { return m_matrix; } 00398 00400 EIGEN_DEVICE_FUNC inline ConstLinearPart linear() const { return ConstLinearPart(m_matrix,0,0); } 00402 EIGEN_DEVICE_FUNC inline LinearPart linear() { return LinearPart(m_matrix,0,0); } 00403 00405 EIGEN_DEVICE_FUNC inline ConstAffinePart affine() const { return take_affine_part::run(m_matrix); } 00407 EIGEN_DEVICE_FUNC inline AffinePart affine() { return take_affine_part::run(m_matrix); } 00408 00410 EIGEN_DEVICE_FUNC inline ConstTranslationPart translation() const { return ConstTranslationPart(m_matrix,0,Dim); } 00412 EIGEN_DEVICE_FUNC inline TranslationPart translation() { return TranslationPart(m_matrix,0,Dim); } 00413 00438 // note: this function is defined here because some compilers cannot find the respective declaration 00439 template<typename OtherDerived> 00440 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename internal::transform_right_product_impl<Transform, OtherDerived>::ResultType 00441 operator * (const EigenBase<OtherDerived> &other) const 00442 { return internal::transform_right_product_impl<Transform, OtherDerived>::run(*this,other.derived()); } 00443 00451 template<typename OtherDerived> friend 00452 EIGEN_DEVICE_FUNC inline const typename internal::transform_left_product_impl<OtherDerived,Mode,Options,_Dim,_Dim+1>::ResultType 00453 operator * (const EigenBase<OtherDerived> &a, const Transform &b) 00454 { return internal::transform_left_product_impl<OtherDerived,Mode,Options,Dim,HDim>::run(a.derived(),b); } 00455 00462 template<typename DiagonalDerived> 00463 EIGEN_DEVICE_FUNC inline const TransformTimeDiagonalReturnType 00464 operator * (const DiagonalBase<DiagonalDerived> &b) const 00465 { 00466 TransformTimeDiagonalReturnType res(*this); 00467 res.linearExt() *= b; 00468 return res; 00469 } 00470 00477 template<typename DiagonalDerived> 00478 EIGEN_DEVICE_FUNC friend inline TransformTimeDiagonalReturnType 00479 operator * (const DiagonalBase<DiagonalDerived> &a, const Transform &b) 00480 { 00481 TransformTimeDiagonalReturnType res; 00482 res.linear().noalias() = a*b.linear(); 00483 res.translation().noalias() = a*b.translation(); 00484 if (Mode!=int(AffineCompact)) 00485 res.matrix().row(Dim) = b.matrix().row(Dim); 00486 return res; 00487 } 00488 00489 template<typename OtherDerived> 00490 EIGEN_DEVICE_FUNC inline Transform& operator*=(const EigenBase<OtherDerived>& other) { return *this = *this * other; } 00491 00493 EIGEN_DEVICE_FUNC inline const Transform operator * (const Transform& other) const 00494 { 00495 return internal::transform_transform_product_impl<Transform,Transform>::run(*this,other); 00496 } 00497 00498 #if EIGEN_COMP_ICC 00499 private: 00500 // this intermediate structure permits to workaround a bug in ICC 11: 00501 // error: template instantiation resulted in unexpected function type of "Eigen::Transform<double, 3, 32, 0> 00502 // (const Eigen::Transform<double, 3, 2, 0> &) const" 00503 // (the meaning of a name may have changed since the template declaration -- the type of the template is: 00504 // "Eigen::internal::transform_transform_product_impl<Eigen::Transform<double, 3, 32, 0>, 00505 // Eigen::Transform<double, 3, Mode, Options>, <expression>>::ResultType (const Eigen::Transform<double, 3, Mode, Options> &) const") 00506 // 00507 template<int OtherMode,int OtherOptions> struct icc_11_workaround 00508 { 00509 typedef internal::transform_transform_product_impl<Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> > ProductType; 00510 typedef typename ProductType::ResultType ResultType; 00511 }; 00512 00513 public: 00515 template<int OtherMode,int OtherOptions> 00516 inline typename icc_11_workaround<OtherMode,OtherOptions>::ResultType 00517 operator * (const Transform<Scalar,Dim,OtherMode,OtherOptions>& other) const 00518 { 00519 typedef typename icc_11_workaround<OtherMode,OtherOptions>::ProductType ProductType; 00520 return ProductType::run(*this,other); 00521 } 00522 #else 00523 00524 template<int OtherMode,int OtherOptions> 00525 EIGEN_DEVICE_FUNC inline typename internal::transform_transform_product_impl<Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> >::ResultType 00526 operator * (const Transform<Scalar,Dim,OtherMode,OtherOptions>& other) const 00527 { 00528 return internal::transform_transform_product_impl<Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> >::run(*this,other); 00529 } 00530 #endif 00531 00533 EIGEN_DEVICE_FUNC void setIdentity() { m_matrix.setIdentity(); } 00534 00539 EIGEN_DEVICE_FUNC static const Transform Identity() 00540 { 00541 return Transform(MatrixType::Identity()); 00542 } 00543 00544 template<typename OtherDerived> 00545 EIGEN_DEVICE_FUNC 00546 inline Transform& scale(const MatrixBase<OtherDerived> &other); 00547 00548 template<typename OtherDerived> 00549 EIGEN_DEVICE_FUNC 00550 inline Transform& prescale(const MatrixBase<OtherDerived> &other); 00551 00552 EIGEN_DEVICE_FUNC inline Transform& scale(const Scalar& s); 00553 EIGEN_DEVICE_FUNC inline Transform& prescale(const Scalar& s); 00554 00555 template<typename OtherDerived> 00556 EIGEN_DEVICE_FUNC 00557 inline Transform& translate(const MatrixBase<OtherDerived> &other); 00558 00559 template<typename OtherDerived> 00560 EIGEN_DEVICE_FUNC 00561 inline Transform& pretranslate(const MatrixBase<OtherDerived> &other); 00562 00563 template<typename RotationType> 00564 EIGEN_DEVICE_FUNC 00565 inline Transform& rotate(const RotationType& rotation); 00566 00567 template<typename RotationType> 00568 EIGEN_DEVICE_FUNC 00569 inline Transform& prerotate(const RotationType& rotation); 00570 00571 EIGEN_DEVICE_FUNC Transform& shear(const Scalar& sx, const Scalar& sy); 00572 EIGEN_DEVICE_FUNC Transform& preshear(const Scalar& sx, const Scalar& sy); 00573 00574 EIGEN_DEVICE_FUNC inline Transform& operator=(const TranslationType& t); 00575 00576 EIGEN_DEVICE_FUNC 00577 inline Transform& operator*=(const TranslationType& t) { return translate(t.vector()); } 00578 00579 EIGEN_DEVICE_FUNC inline Transform operator*(const TranslationType& t) const; 00580 00581 EIGEN_DEVICE_FUNC 00582 inline Transform& operator=(const UniformScaling<Scalar>& t); 00583 00584 EIGEN_DEVICE_FUNC 00585 inline Transform& operator*=(const UniformScaling<Scalar>& s) { return scale(s.factor()); } 00586 00587 EIGEN_DEVICE_FUNC 00588 inline TransformTimeDiagonalReturnType operator*(const UniformScaling<Scalar>& s) const 00589 { 00590 TransformTimeDiagonalReturnType res = *this; 00591 res.scale(s.factor()); 00592 return res; 00593 } 00594 00595 EIGEN_DEVICE_FUNC 00596 inline Transform& operator*=(const DiagonalMatrix<Scalar,Dim>& s) { linearExt() *= s; return *this; } 00597 00598 template<typename Derived> 00599 EIGEN_DEVICE_FUNC inline Transform& operator=(const RotationBase<Derived,Dim>& r); 00600 template<typename Derived> 00601 EIGEN_DEVICE_FUNC inline Transform& operator*=(const RotationBase<Derived,Dim>& r) { return rotate(r.toRotationMatrix()); } 00602 template<typename Derived> 00603 EIGEN_DEVICE_FUNC inline Transform operator*(const RotationBase<Derived,Dim>& r) const; 00604 00605 EIGEN_DEVICE_FUNC const LinearMatrixType rotation() const; 00606 template<typename RotationMatrixType, typename ScalingMatrixType> 00607 EIGEN_DEVICE_FUNC 00608 void computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const; 00609 template<typename ScalingMatrixType, typename RotationMatrixType> 00610 EIGEN_DEVICE_FUNC 00611 void computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const; 00612 00613 template<typename PositionDerived, typename OrientationType, typename ScaleDerived> 00614 EIGEN_DEVICE_FUNC 00615 Transform& fromPositionOrientationScale(const MatrixBase<PositionDerived> &position, 00616 const OrientationType& orientation, const MatrixBase<ScaleDerived> &scale); 00617 00618 EIGEN_DEVICE_FUNC 00619 inline Transform inverse(TransformTraits traits = (TransformTraits)Mode) const; 00620 00622 EIGEN_DEVICE_FUNC const Scalar* data() const { return m_matrix.data(); } 00624 EIGEN_DEVICE_FUNC Scalar* data() { return m_matrix.data(); } 00625 00631 template<typename NewScalarType> 00632 EIGEN_DEVICE_FUNC inline typename internal::cast_return_type<Transform,Transform<NewScalarType,Dim,Mode,Options> >::type cast() const 00633 { return typename internal::cast_return_type<Transform,Transform<NewScalarType,Dim,Mode,Options> >::type(*this); } 00634 00636 template<typename OtherScalarType> 00637 EIGEN_DEVICE_FUNC inline explicit Transform(const Transform<OtherScalarType,Dim,Mode,Options>& other) 00638 { 00639 check_template_params(); 00640 m_matrix = other.matrix().template cast<Scalar>(); 00641 } 00642 00647 EIGEN_DEVICE_FUNC bool isApprox(const Transform& other, const typename NumTraits<Scalar>::Real& prec = NumTraits<Scalar>::dummy_precision()) const 00648 { return m_matrix.isApprox(other.m_matrix, prec); } 00649 00652 EIGEN_DEVICE_FUNC void makeAffine() 00653 { 00654 internal::transform_make_affine<int(Mode)>::run(m_matrix); 00655 } 00656 00661 EIGEN_DEVICE_FUNC inline Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,Dim> linearExt() 00662 { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,Dim>(0,0); } 00667 EIGEN_DEVICE_FUNC inline const Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,Dim> linearExt() const 00668 { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,Dim>(0,0); } 00669 00674 EIGEN_DEVICE_FUNC inline Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,1> translationExt() 00675 { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,1>(0,Dim); } 00680 EIGEN_DEVICE_FUNC inline const Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,1> translationExt() const 00681 { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,1>(0,Dim); } 00682 00683 00684 #ifdef EIGEN_TRANSFORM_PLUGIN 00685 #include EIGEN_TRANSFORM_PLUGIN 00686 #endif 00687 00688 protected: 00689 #ifndef EIGEN_PARSED_BY_DOXYGEN 00690 EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void check_template_params() 00691 { 00692 EIGEN_STATIC_ASSERT((Options & (DontAlign|RowMajor)) == Options, INVALID_MATRIX_TEMPLATE_PARAMETERS) 00693 } 00694 #endif 00695 00696 }; 00697 00699 typedef Transform<float,2,Isometry> Isometry2f; 00701 typedef Transform<float,3,Isometry> Isometry3f; 00703 typedef Transform<double,2,Isometry> Isometry2d; 00705 typedef Transform<double,3,Isometry> Isometry3d; 00706 00708 typedef Transform<float,2,Affine> Affine2f; 00710 typedef Transform<float,3,Affine> Affine3f; 00712 typedef Transform<double,2,Affine> Affine2d; 00714 typedef Transform<double,3,Affine> Affine3d; 00715 00717 typedef Transform<float,2,AffineCompact> AffineCompact2f; 00719 typedef Transform<float,3,AffineCompact> AffineCompact3f; 00721 typedef Transform<double,2,AffineCompact> AffineCompact2d; 00723 typedef Transform<double,3,AffineCompact> AffineCompact3d; 00724 00726 typedef Transform<float,2,Projective> Projective2f; 00728 typedef Transform<float,3,Projective> Projective3f; 00730 typedef Transform<double,2,Projective> Projective2d; 00732 typedef Transform<double,3,Projective> Projective3d; 00733 00734 /************************** 00735 *** Optional QT support *** 00736 **************************/ 00737 00738 #ifdef EIGEN_QT_SUPPORT 00739 00743 template<typename Scalar, int Dim, int Mode,int Options> 00744 Transform<Scalar,Dim,Mode,Options>::Transform(const QMatrix& other) 00745 { 00746 check_template_params(); 00747 *this = other; 00748 } 00749 00754 template<typename Scalar, int Dim, int Mode,int Options> 00755 Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const QMatrix& other) 00756 { 00757 EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE) 00758 if (Mode == int(AffineCompact)) 00759 m_matrix << other.m11(), other.m21(), other.dx(), 00760 other.m12(), other.m22(), other.dy(); 00761 else 00762 m_matrix << other.m11(), other.m21(), other.dx(), 00763 other.m12(), other.m22(), other.dy(), 00764 0, 0, 1; 00765 return *this; 00766 } 00767 00774 template<typename Scalar, int Dim, int Mode, int Options> 00775 QMatrix Transform<Scalar,Dim,Mode,Options>::toQMatrix(void) const 00776 { 00777 check_template_params(); 00778 EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE) 00779 return QMatrix(m_matrix.coeff(0,0), m_matrix.coeff(1,0), 00780 m_matrix.coeff(0,1), m_matrix.coeff(1,1), 00781 m_matrix.coeff(0,2), m_matrix.coeff(1,2)); 00782 } 00783 00788 template<typename Scalar, int Dim, int Mode,int Options> 00789 Transform<Scalar,Dim,Mode,Options>::Transform(const QTransform& other) 00790 { 00791 check_template_params(); 00792 *this = other; 00793 } 00794 00799 template<typename Scalar, int Dim, int Mode, int Options> 00800 Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const QTransform& other) 00801 { 00802 check_template_params(); 00803 EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE) 00804 if (Mode == int(AffineCompact)) 00805 m_matrix << other.m11(), other.m21(), other.dx(), 00806 other.m12(), other.m22(), other.dy(); 00807 else 00808 m_matrix << other.m11(), other.m21(), other.dx(), 00809 other.m12(), other.m22(), other.dy(), 00810 other.m13(), other.m23(), other.m33(); 00811 return *this; 00812 } 00813 00818 template<typename Scalar, int Dim, int Mode, int Options> 00819 QTransform Transform<Scalar,Dim,Mode,Options>::toQTransform(void) const 00820 { 00821 EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE) 00822 if (Mode == int(AffineCompact)) 00823 return QTransform(m_matrix.coeff(0,0), m_matrix.coeff(1,0), 00824 m_matrix.coeff(0,1), m_matrix.coeff(1,1), 00825 m_matrix.coeff(0,2), m_matrix.coeff(1,2)); 00826 else 00827 return QTransform(m_matrix.coeff(0,0), m_matrix.coeff(1,0), m_matrix.coeff(2,0), 00828 m_matrix.coeff(0,1), m_matrix.coeff(1,1), m_matrix.coeff(2,1), 00829 m_matrix.coeff(0,2), m_matrix.coeff(1,2), m_matrix.coeff(2,2)); 00830 } 00831 #endif 00832 00833 /********************* 00834 *** Procedural API *** 00835 *********************/ 00836 00841 template<typename Scalar, int Dim, int Mode, int Options> 00842 template<typename OtherDerived> 00843 EIGEN_DEVICE_FUNC Transform<Scalar,Dim,Mode,Options>& 00844 Transform<Scalar,Dim,Mode,Options>::scale(const MatrixBase<OtherDerived> &other) 00845 { 00846 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) 00847 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) 00848 linearExt().noalias() = (linearExt() * other.asDiagonal()); 00849 return *this; 00850 } 00851 00856 template<typename Scalar, int Dim, int Mode, int Options> 00857 EIGEN_DEVICE_FUNC inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::scale(const Scalar& s) 00858 { 00859 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) 00860 linearExt() *= s; 00861 return *this; 00862 } 00863 00868 template<typename Scalar, int Dim, int Mode, int Options> 00869 template<typename OtherDerived> 00870 EIGEN_DEVICE_FUNC Transform<Scalar,Dim,Mode,Options>& 00871 Transform<Scalar,Dim,Mode,Options>::prescale(const MatrixBase<OtherDerived> &other) 00872 { 00873 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) 00874 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) 00875 affine().noalias() = (other.asDiagonal() * affine()); 00876 return *this; 00877 } 00878 00883 template<typename Scalar, int Dim, int Mode, int Options> 00884 EIGEN_DEVICE_FUNC inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::prescale(const Scalar& s) 00885 { 00886 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) 00887 m_matrix.template topRows<Dim>() *= s; 00888 return *this; 00889 } 00890 00895 template<typename Scalar, int Dim, int Mode, int Options> 00896 template<typename OtherDerived> 00897 EIGEN_DEVICE_FUNC Transform<Scalar,Dim,Mode,Options>& 00898 Transform<Scalar,Dim,Mode,Options>::translate(const MatrixBase<OtherDerived> &other) 00899 { 00900 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) 00901 translationExt() += linearExt() * other; 00902 return *this; 00903 } 00904 00909 template<typename Scalar, int Dim, int Mode, int Options> 00910 template<typename OtherDerived> 00911 EIGEN_DEVICE_FUNC Transform<Scalar,Dim,Mode,Options>& 00912 Transform<Scalar,Dim,Mode,Options>::pretranslate(const MatrixBase<OtherDerived> &other) 00913 { 00914 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) 00915 if(int(Mode)==int(Projective)) 00916 affine() += other * m_matrix.row(Dim); 00917 else 00918 translation() += other; 00919 return *this; 00920 } 00921 00939 template<typename Scalar, int Dim, int Mode, int Options> 00940 template<typename RotationType> 00941 EIGEN_DEVICE_FUNC Transform<Scalar,Dim,Mode,Options>& 00942 Transform<Scalar,Dim,Mode,Options>::rotate(const RotationType& rotation) 00943 { 00944 linearExt() *= internal::toRotationMatrix<Scalar,Dim>(rotation); 00945 return *this; 00946 } 00947 00955 template<typename Scalar, int Dim, int Mode, int Options> 00956 template<typename RotationType> 00957 EIGEN_DEVICE_FUNC Transform<Scalar,Dim,Mode,Options>& 00958 Transform<Scalar,Dim,Mode,Options>::prerotate(const RotationType& rotation) 00959 { 00960 m_matrix.template block<Dim,HDim>(0,0) = internal::toRotationMatrix<Scalar,Dim>(rotation) 00961 * m_matrix.template block<Dim,HDim>(0,0); 00962 return *this; 00963 } 00964 00970 template<typename Scalar, int Dim, int Mode, int Options> 00971 EIGEN_DEVICE_FUNC Transform<Scalar,Dim,Mode,Options>& 00972 Transform<Scalar,Dim,Mode,Options>::shear(const Scalar& sx, const Scalar& sy) 00973 { 00974 EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE) 00975 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) 00976 VectorType tmp = linear().col(0)*sy + linear().col(1); 00977 linear() << linear().col(0) + linear().col(1)*sx, tmp; 00978 return *this; 00979 } 00980 00986 template<typename Scalar, int Dim, int Mode, int Options> 00987 EIGEN_DEVICE_FUNC Transform<Scalar,Dim,Mode,Options>& 00988 Transform<Scalar,Dim,Mode,Options>::preshear(const Scalar& sx, const Scalar& sy) 00989 { 00990 EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE) 00991 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) 00992 m_matrix.template block<Dim,HDim>(0,0) = LinearMatrixType(1, sx, sy, 1) * m_matrix.template block<Dim,HDim>(0,0); 00993 return *this; 00994 } 00995 00996 /****************************************************** 00997 *** Scaling, Translation and Rotation compatibility *** 00998 ******************************************************/ 00999 01000 template<typename Scalar, int Dim, int Mode, int Options> 01001 EIGEN_DEVICE_FUNC inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const TranslationType& t) 01002 { 01003 linear().setIdentity(); 01004 translation() = t.vector(); 01005 makeAffine(); 01006 return *this; 01007 } 01008 01009 template<typename Scalar, int Dim, int Mode, int Options> 01010 EIGEN_DEVICE_FUNC inline Transform<Scalar,Dim,Mode,Options> Transform<Scalar,Dim,Mode,Options>::operator*(const TranslationType& t) const 01011 { 01012 Transform res = *this; 01013 res.translate(t.vector()); 01014 return res; 01015 } 01016 01017 template<typename Scalar, int Dim, int Mode, int Options> 01018 EIGEN_DEVICE_FUNC inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const UniformScaling<Scalar>& s) 01019 { 01020 m_matrix.setZero(); 01021 linear().diagonal().fill(s.factor()); 01022 makeAffine(); 01023 return *this; 01024 } 01025 01026 template<typename Scalar, int Dim, int Mode, int Options> 01027 template<typename Derived> 01028 EIGEN_DEVICE_FUNC inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const RotationBase<Derived,Dim>& r) 01029 { 01030 linear() = internal::toRotationMatrix<Scalar,Dim>(r); 01031 translation().setZero(); 01032 makeAffine(); 01033 return *this; 01034 } 01035 01036 template<typename Scalar, int Dim, int Mode, int Options> 01037 template<typename Derived> 01038 EIGEN_DEVICE_FUNC inline Transform<Scalar,Dim,Mode,Options> Transform<Scalar,Dim,Mode,Options>::operator*(const RotationBase<Derived,Dim>& r) const 01039 { 01040 Transform res = *this; 01041 res.rotate(r.derived()); 01042 return res; 01043 } 01044 01045 /************************ 01046 *** Special functions *** 01047 ************************/ 01048 01056 template<typename Scalar, int Dim, int Mode, int Options> 01057 EIGEN_DEVICE_FUNC const typename Transform<Scalar,Dim,Mode,Options>::LinearMatrixType 01058 Transform<Scalar,Dim,Mode,Options>::rotation() const 01059 { 01060 LinearMatrixType result; 01061 computeRotationScaling(&result, (LinearMatrixType*)0); 01062 return result; 01063 } 01064 01065 01077 template<typename Scalar, int Dim, int Mode, int Options> 01078 template<typename RotationMatrixType, typename ScalingMatrixType> 01079 EIGEN_DEVICE_FUNC void Transform<Scalar,Dim,Mode,Options>::computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const 01080 { 01081 JacobiSVD<LinearMatrixType> svd(linear(), ComputeFullU | ComputeFullV); 01082 01083 Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant(); // so x has absolute value 1 01084 VectorType sv(svd.singularValues()); 01085 sv.coeffRef(0) *= x; 01086 if(scaling) scaling->lazyAssign(svd.matrixV() * sv.asDiagonal() * svd.matrixV().adjoint()); 01087 if(rotation) 01088 { 01089 LinearMatrixType m(svd.matrixU()); 01090 m.col(0) /= x; 01091 rotation->lazyAssign(m * svd.matrixV().adjoint()); 01092 } 01093 } 01094 01106 template<typename Scalar, int Dim, int Mode, int Options> 01107 template<typename ScalingMatrixType, typename RotationMatrixType> 01108 EIGEN_DEVICE_FUNC void Transform<Scalar,Dim,Mode,Options>::computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const 01109 { 01110 JacobiSVD<LinearMatrixType> svd(linear(), ComputeFullU | ComputeFullV); 01111 01112 Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant(); // so x has absolute value 1 01113 VectorType sv(svd.singularValues()); 01114 sv.coeffRef(0) *= x; 01115 if(scaling) scaling->lazyAssign(svd.matrixU() * sv.asDiagonal() * svd.matrixU().adjoint()); 01116 if(rotation) 01117 { 01118 LinearMatrixType m(svd.matrixU()); 01119 m.col(0) /= x; 01120 rotation->lazyAssign(m * svd.matrixV().adjoint()); 01121 } 01122 } 01123 01127 template<typename Scalar, int Dim, int Mode, int Options> 01128 template<typename PositionDerived, typename OrientationType, typename ScaleDerived> 01129 EIGEN_DEVICE_FUNC Transform<Scalar,Dim,Mode,Options>& 01130 Transform<Scalar,Dim,Mode,Options>::fromPositionOrientationScale(const MatrixBase<PositionDerived> &position, 01131 const OrientationType& orientation, const MatrixBase<ScaleDerived> &scale) 01132 { 01133 linear() = internal::toRotationMatrix<Scalar,Dim>(orientation); 01134 linear() *= scale.asDiagonal(); 01135 translation() = position; 01136 makeAffine(); 01137 return *this; 01138 } 01139 01140 namespace internal { 01141 01142 template<int Mode> 01143 struct transform_make_affine 01144 { 01145 template<typename MatrixType> 01146 EIGEN_DEVICE_FUNC static void run(MatrixType &mat) 01147 { 01148 static const int Dim = MatrixType::ColsAtCompileTime-1; 01149 mat.template block<1,Dim>(Dim,0).setZero(); 01150 mat.coeffRef(Dim,Dim) = typename MatrixType::Scalar(1); 01151 } 01152 }; 01153 01154 template<> 01155 struct transform_make_affine<AffineCompact> 01156 { 01157 template<typename MatrixType> EIGEN_DEVICE_FUNC static void run(MatrixType &) { } 01158 }; 01159 01160 // selector needed to avoid taking the inverse of a 3x4 matrix 01161 template<typename TransformType, int Mode=TransformType::Mode> 01162 struct projective_transform_inverse 01163 { 01164 EIGEN_DEVICE_FUNC static inline void run(const TransformType&, TransformType&) 01165 {} 01166 }; 01167 01168 template<typename TransformType> 01169 struct projective_transform_inverse<TransformType, Projective> 01170 { 01171 EIGEN_DEVICE_FUNC static inline void run(const TransformType& m, TransformType& res) 01172 { 01173 res.matrix() = m.matrix().inverse(); 01174 } 01175 }; 01176 01177 } // end namespace internal 01178 01179 01200 template<typename Scalar, int Dim, int Mode, int Options> 01201 EIGEN_DEVICE_FUNC Transform<Scalar,Dim,Mode,Options> 01202 Transform<Scalar,Dim,Mode,Options>::inverse(TransformTraits hint) const 01203 { 01204 Transform res; 01205 if (hint == Projective) 01206 { 01207 internal::projective_transform_inverse<Transform>::run(*this, res); 01208 } 01209 else 01210 { 01211 if (hint == Isometry) 01212 { 01213 res.matrix().template topLeftCorner<Dim,Dim>() = linear().transpose(); 01214 } 01215 else if(hint&Affine) 01216 { 01217 res.matrix().template topLeftCorner<Dim,Dim>() = linear().inverse(); 01218 } 01219 else 01220 { 01221 eigen_assert(false && "Invalid transform traits in Transform::Inverse"); 01222 } 01223 // translation and remaining parts 01224 res.matrix().template topRightCorner<Dim,1>() 01225 = - res.matrix().template topLeftCorner<Dim,Dim>() * translation(); 01226 res.makeAffine(); // we do need this, because in the beginning res is uninitialized 01227 } 01228 return res; 01229 } 01230 01231 namespace internal { 01232 01233 /***************************************************** 01234 *** Specializations of take affine part *** 01235 *****************************************************/ 01236 01237 template<typename TransformType> struct transform_take_affine_part { 01238 typedef typename TransformType::MatrixType MatrixType; 01239 typedef typename TransformType::AffinePart AffinePart; 01240 typedef typename TransformType::ConstAffinePart ConstAffinePart; 01241 static inline AffinePart run(MatrixType& m) 01242 { return m.template block<TransformType::Dim,TransformType::HDim>(0,0); } 01243 static inline ConstAffinePart run(const MatrixType& m) 01244 { return m.template block<TransformType::Dim,TransformType::HDim>(0,0); } 01245 }; 01246 01247 template<typename Scalar, int Dim, int Options> 01248 struct transform_take_affine_part<Transform<Scalar,Dim,AffineCompact, Options> > { 01249 typedef typename Transform<Scalar,Dim,AffineCompact,Options>::MatrixType MatrixType; 01250 static inline MatrixType& run(MatrixType& m) { return m; } 01251 static inline const MatrixType& run(const MatrixType& m) { return m; } 01252 }; 01253 01254 /***************************************************** 01255 *** Specializations of construct from matrix *** 01256 *****************************************************/ 01257 01258 template<typename Other, int Mode, int Options, int Dim, int HDim> 01259 struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, Dim,Dim> 01260 { 01261 static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other) 01262 { 01263 transform->linear() = other; 01264 transform->translation().setZero(); 01265 transform->makeAffine(); 01266 } 01267 }; 01268 01269 template<typename Other, int Mode, int Options, int Dim, int HDim> 01270 struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, Dim,HDim> 01271 { 01272 static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other) 01273 { 01274 transform->affine() = other; 01275 transform->makeAffine(); 01276 } 01277 }; 01278 01279 template<typename Other, int Mode, int Options, int Dim, int HDim> 01280 struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, HDim,HDim> 01281 { 01282 static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other) 01283 { transform->matrix() = other; } 01284 }; 01285 01286 template<typename Other, int Options, int Dim, int HDim> 01287 struct transform_construct_from_matrix<Other, AffineCompact,Options,Dim,HDim, HDim,HDim> 01288 { 01289 static inline void run(Transform<typename Other::Scalar,Dim,AffineCompact,Options> *transform, const Other& other) 01290 { transform->matrix() = other.template block<Dim,HDim>(0,0); } 01291 }; 01292 01293 /********************************************************** 01294 *** Specializations of operator* with rhs EigenBase *** 01295 **********************************************************/ 01296 01297 template<int LhsMode,int RhsMode> 01298 struct transform_product_result 01299 { 01300 enum 01301 { 01302 Mode = 01303 (LhsMode == (int)Projective || RhsMode == (int)Projective ) ? Projective : 01304 (LhsMode == (int)Affine || RhsMode == (int)Affine ) ? Affine : 01305 (LhsMode == (int)AffineCompact || RhsMode == (int)AffineCompact ) ? AffineCompact : 01306 (LhsMode == (int)Isometry || RhsMode == (int)Isometry ) ? Isometry : Projective 01307 }; 01308 }; 01309 01310 template< typename TransformType, typename MatrixType, int RhsCols> 01311 struct transform_right_product_impl< TransformType, MatrixType, 0, RhsCols> 01312 { 01313 typedef typename MatrixType::PlainObject ResultType; 01314 01315 static EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other) 01316 { 01317 return T.matrix() * other; 01318 } 01319 }; 01320 01321 template< typename TransformType, typename MatrixType, int RhsCols> 01322 struct transform_right_product_impl< TransformType, MatrixType, 1, RhsCols> 01323 { 01324 enum { 01325 Dim = TransformType::Dim, 01326 HDim = TransformType::HDim, 01327 OtherRows = MatrixType::RowsAtCompileTime, 01328 OtherCols = MatrixType::ColsAtCompileTime 01329 }; 01330 01331 typedef typename MatrixType::PlainObject ResultType; 01332 01333 static EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other) 01334 { 01335 EIGEN_STATIC_ASSERT(OtherRows==HDim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES); 01336 01337 typedef Block<ResultType, Dim, OtherCols, int(MatrixType::RowsAtCompileTime)==Dim> TopLeftLhs; 01338 01339 ResultType res(other.rows(),other.cols()); 01340 TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() = T.affine() * other; 01341 res.row(OtherRows-1) = other.row(OtherRows-1); 01342 01343 return res; 01344 } 01345 }; 01346 01347 template< typename TransformType, typename MatrixType, int RhsCols> 01348 struct transform_right_product_impl< TransformType, MatrixType, 2, RhsCols> 01349 { 01350 enum { 01351 Dim = TransformType::Dim, 01352 HDim = TransformType::HDim, 01353 OtherRows = MatrixType::RowsAtCompileTime, 01354 OtherCols = MatrixType::ColsAtCompileTime 01355 }; 01356 01357 typedef typename MatrixType::PlainObject ResultType; 01358 01359 static EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other) 01360 { 01361 EIGEN_STATIC_ASSERT(OtherRows==Dim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES); 01362 01363 typedef Block<ResultType, Dim, OtherCols, true> TopLeftLhs; 01364 ResultType res(Replicate<typename TransformType::ConstTranslationPart, 1, OtherCols>(T.translation(),1,other.cols())); 01365 TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() += T.linear() * other; 01366 01367 return res; 01368 } 01369 }; 01370 01371 template< typename TransformType, typename MatrixType > 01372 struct transform_right_product_impl< TransformType, MatrixType, 2, 1> // rhs is a vector of size Dim 01373 { 01374 typedef typename TransformType::MatrixType TransformMatrix; 01375 enum { 01376 Dim = TransformType::Dim, 01377 HDim = TransformType::HDim, 01378 OtherRows = MatrixType::RowsAtCompileTime, 01379 WorkingRows = EIGEN_PLAIN_ENUM_MIN(TransformMatrix::RowsAtCompileTime,HDim) 01380 }; 01381 01382 typedef typename MatrixType::PlainObject ResultType; 01383 01384 static EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other) 01385 { 01386 EIGEN_STATIC_ASSERT(OtherRows==Dim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES); 01387 01388 Matrix<typename ResultType::Scalar, Dim+1, 1> rhs; 01389 rhs.template head<Dim>() = other; rhs[Dim] = typename ResultType::Scalar(1); 01390 Matrix<typename ResultType::Scalar, WorkingRows, 1> res(T.matrix() * rhs); 01391 return res.template head<Dim>(); 01392 } 01393 }; 01394 01395 /********************************************************** 01396 *** Specializations of operator* with lhs EigenBase *** 01397 **********************************************************/ 01398 01399 // generic HDim x HDim matrix * T => Projective 01400 template<typename Other,int Mode, int Options, int Dim, int HDim> 01401 struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, HDim,HDim> 01402 { 01403 typedef Transform<typename Other::Scalar,Dim,Mode,Options> TransformType; 01404 typedef typename TransformType::MatrixType MatrixType; 01405 typedef Transform<typename Other::Scalar,Dim,Projective,Options> ResultType; 01406 static ResultType run(const Other& other,const TransformType& tr) 01407 { return ResultType(other * tr.matrix()); } 01408 }; 01409 01410 // generic HDim x HDim matrix * AffineCompact => Projective 01411 template<typename Other, int Options, int Dim, int HDim> 01412 struct transform_left_product_impl<Other,AffineCompact,Options,Dim,HDim, HDim,HDim> 01413 { 01414 typedef Transform<typename Other::Scalar,Dim,AffineCompact,Options> TransformType; 01415 typedef typename TransformType::MatrixType MatrixType; 01416 typedef Transform<typename Other::Scalar,Dim,Projective,Options> ResultType; 01417 static ResultType run(const Other& other,const TransformType& tr) 01418 { 01419 ResultType res; 01420 res.matrix().noalias() = other.template block<HDim,Dim>(0,0) * tr.matrix(); 01421 res.matrix().col(Dim) += other.col(Dim); 01422 return res; 01423 } 01424 }; 01425 01426 // affine matrix * T 01427 template<typename Other,int Mode, int Options, int Dim, int HDim> 01428 struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, Dim,HDim> 01429 { 01430 typedef Transform<typename Other::Scalar,Dim,Mode,Options> TransformType; 01431 typedef typename TransformType::MatrixType MatrixType; 01432 typedef TransformType ResultType; 01433 static ResultType run(const Other& other,const TransformType& tr) 01434 { 01435 ResultType res; 01436 res.affine().noalias() = other * tr.matrix(); 01437 res.matrix().row(Dim) = tr.matrix().row(Dim); 01438 return res; 01439 } 01440 }; 01441 01442 // affine matrix * AffineCompact 01443 template<typename Other, int Options, int Dim, int HDim> 01444 struct transform_left_product_impl<Other,AffineCompact,Options,Dim,HDim, Dim,HDim> 01445 { 01446 typedef Transform<typename Other::Scalar,Dim,AffineCompact,Options> TransformType; 01447 typedef typename TransformType::MatrixType MatrixType; 01448 typedef TransformType ResultType; 01449 static ResultType run(const Other& other,const TransformType& tr) 01450 { 01451 ResultType res; 01452 res.matrix().noalias() = other.template block<Dim,Dim>(0,0) * tr.matrix(); 01453 res.translation() += other.col(Dim); 01454 return res; 01455 } 01456 }; 01457 01458 // linear matrix * T 01459 template<typename Other,int Mode, int Options, int Dim, int HDim> 01460 struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, Dim,Dim> 01461 { 01462 typedef Transform<typename Other::Scalar,Dim,Mode,Options> TransformType; 01463 typedef typename TransformType::MatrixType MatrixType; 01464 typedef TransformType ResultType; 01465 static ResultType run(const Other& other, const TransformType& tr) 01466 { 01467 TransformType res; 01468 if(Mode!=int(AffineCompact)) 01469 res.matrix().row(Dim) = tr.matrix().row(Dim); 01470 res.matrix().template topRows<Dim>().noalias() 01471 = other * tr.matrix().template topRows<Dim>(); 01472 return res; 01473 } 01474 }; 01475 01476 /********************************************************** 01477 *** Specializations of operator* with another Transform *** 01478 **********************************************************/ 01479 01480 template<typename Scalar, int Dim, int LhsMode, int LhsOptions, int RhsMode, int RhsOptions> 01481 struct transform_transform_product_impl<Transform<Scalar,Dim,LhsMode,LhsOptions>,Transform<Scalar,Dim,RhsMode,RhsOptions>,false > 01482 { 01483 enum { ResultMode = transform_product_result<LhsMode,RhsMode>::Mode }; 01484 typedef Transform<Scalar,Dim,LhsMode,LhsOptions> Lhs; 01485 typedef Transform<Scalar,Dim,RhsMode,RhsOptions> Rhs; 01486 typedef Transform<Scalar,Dim,ResultMode,LhsOptions> ResultType; 01487 static ResultType run(const Lhs& lhs, const Rhs& rhs) 01488 { 01489 ResultType res; 01490 res.linear() = lhs.linear() * rhs.linear(); 01491 res.translation() = lhs.linear() * rhs.translation() + lhs.translation(); 01492 res.makeAffine(); 01493 return res; 01494 } 01495 }; 01496 01497 template<typename Scalar, int Dim, int LhsMode, int LhsOptions, int RhsMode, int RhsOptions> 01498 struct transform_transform_product_impl<Transform<Scalar,Dim,LhsMode,LhsOptions>,Transform<Scalar,Dim,RhsMode,RhsOptions>,true > 01499 { 01500 typedef Transform<Scalar,Dim,LhsMode,LhsOptions> Lhs; 01501 typedef Transform<Scalar,Dim,RhsMode,RhsOptions> Rhs; 01502 typedef Transform<Scalar,Dim,Projective> ResultType; 01503 static ResultType run(const Lhs& lhs, const Rhs& rhs) 01504 { 01505 return ResultType( lhs.matrix() * rhs.matrix() ); 01506 } 01507 }; 01508 01509 template<typename Scalar, int Dim, int LhsOptions, int RhsOptions> 01510 struct transform_transform_product_impl<Transform<Scalar,Dim,AffineCompact,LhsOptions>,Transform<Scalar,Dim,Projective,RhsOptions>,true > 01511 { 01512 typedef Transform<Scalar,Dim,AffineCompact,LhsOptions> Lhs; 01513 typedef Transform<Scalar,Dim,Projective,RhsOptions> Rhs; 01514 typedef Transform<Scalar,Dim,Projective> ResultType; 01515 static ResultType run(const Lhs& lhs, const Rhs& rhs) 01516 { 01517 ResultType res; 01518 res.matrix().template topRows<Dim>() = lhs.matrix() * rhs.matrix(); 01519 res.matrix().row(Dim) = rhs.matrix().row(Dim); 01520 return res; 01521 } 01522 }; 01523 01524 template<typename Scalar, int Dim, int LhsOptions, int RhsOptions> 01525 struct transform_transform_product_impl<Transform<Scalar,Dim,Projective,LhsOptions>,Transform<Scalar,Dim,AffineCompact,RhsOptions>,true > 01526 { 01527 typedef Transform<Scalar,Dim,Projective,LhsOptions> Lhs; 01528 typedef Transform<Scalar,Dim,AffineCompact,RhsOptions> Rhs; 01529 typedef Transform<Scalar,Dim,Projective> ResultType; 01530 static ResultType run(const Lhs& lhs, const Rhs& rhs) 01531 { 01532 ResultType res(lhs.matrix().template leftCols<Dim>() * rhs.matrix()); 01533 res.matrix().col(Dim) += lhs.matrix().col(Dim); 01534 return res; 01535 } 01536 }; 01537 01538 } // end namespace internal 01539 01540 } // end namespace Eigen 01541 01542 #endif // EIGEN_TRANSFORM_H