00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef EIGEN_TRANSFORM_H
00028 #define EIGEN_TRANSFORM_H
00029
00030 namespace internal {
00031
00032 template<typename Transform>
00033 struct transform_traits
00034 {
00035 enum
00036 {
00037 Dim = Transform::Dim,
00038 HDim = Transform::HDim,
00039 Mode = Transform::Mode,
00040 IsProjective = (Mode==Projective)
00041 };
00042 };
00043
00044 template< typename TransformType,
00045 typename MatrixType,
00046 bool IsProjective = transform_traits<TransformType>::IsProjective>
00047 struct transform_right_product_impl;
00048
00049 template< typename Other,
00050 int Mode,
00051 int Dim,
00052 int HDim,
00053 int OtherRows=Other::RowsAtCompileTime,
00054 int OtherCols=Other::ColsAtCompileTime>
00055 struct transform_left_product_impl;
00056
00057 template< typename Lhs,
00058 typename Rhs,
00059 bool AnyProjective =
00060 transform_traits<Lhs>::IsProjective ||
00061 transform_traits<Lhs>::IsProjective>
00062 struct transform_transform_product_impl;
00063
00064 template< typename Other,
00065 int Mode,
00066 int Dim,
00067 int HDim,
00068 int OtherRows=Other::RowsAtCompileTime,
00069 int OtherCols=Other::ColsAtCompileTime>
00070 struct transform_construct_from_matrix;
00071
00072 template<typename TransformType> struct transform_take_affine_part;
00073
00074 }
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180 template<typename _Scalar, int _Dim, int _Mode>
00181 class Transform
00182 {
00183 public:
00184 EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_Dim==Dynamic ? Dynamic : (_Dim+1)*(_Dim+1))
00185 enum {
00186 Mode = _Mode,
00187 Dim = _Dim,
00188 HDim = _Dim+1,
00189 Rows = int(Mode)==(AffineCompact) ? Dim : HDim
00190 };
00191
00192 typedef _Scalar Scalar;
00193 typedef DenseIndex Index;
00194
00195 typedef Matrix<Scalar,Rows,HDim> MatrixType;
00196
00197 typedef const MatrixType ConstMatrixType;
00198
00199 typedef Matrix<Scalar,Dim,Dim> LinearMatrixType;
00200
00201 typedef Block<MatrixType,Dim,Dim> LinearPart;
00202
00203 typedef const Block<ConstMatrixType,Dim,Dim> ConstLinearPart;
00204
00205 typedef typename internal::conditional<int(Mode)==int(AffineCompact),
00206 MatrixType&,
00207 Block<MatrixType,Dim,HDim> >::type AffinePart;
00208
00209 typedef typename internal::conditional<int(Mode)==int(AffineCompact),
00210 const MatrixType&,
00211 const Block<const MatrixType,Dim,HDim> >::type ConstAffinePart;
00212
00213 typedef Matrix<Scalar,Dim,1> VectorType;
00214
00215 typedef Block<MatrixType,Dim,1> TranslationPart;
00216
00217 typedef const Block<ConstMatrixType,Dim,1> ConstTranslationPart;
00218
00219 typedef Translation<Scalar,Dim> TranslationType;
00220
00221
00222 enum { TransformTimeDiagonalMode = ((Mode==int(Isometry))?Affine:int(Mode)) };
00223
00224 typedef Transform<Scalar,Dim,TransformTimeDiagonalMode> TransformTimeDiagonalReturnType;
00225
00226 protected:
00227
00228 MatrixType m_matrix;
00229
00230 public:
00231
00232
00233
00234 inline Transform()
00235 {
00236 if (int(Mode)==Affine)
00237 makeAffine();
00238 }
00239
00240 inline Transform(const Transform& other)
00241 {
00242 m_matrix = other.m_matrix;
00243 }
00244
00245 inline explicit Transform(const TranslationType& t) { *this = t; }
00246 inline explicit Transform(const UniformScaling<Scalar>& s) { *this = s; }
00247 template<typename Derived>
00248 inline explicit Transform(const RotationBase<Derived, Dim>& r) { *this = r; }
00249
00250 inline Transform& operator=(const Transform& other)
00251 { m_matrix = other.m_matrix; return *this; }
00252
00253 typedef internal::transform_take_affine_part<Transform> take_affine_part;
00254
00255
00256 template<typename OtherDerived>
00257 inline explicit Transform(const EigenBase<OtherDerived>& other)
00258 {
00259 internal::transform_construct_from_matrix<OtherDerived,Mode,Dim,HDim>::run(this, other.derived());
00260 }
00261
00262
00263 template<typename OtherDerived>
00264 inline Transform& operator=(const EigenBase<OtherDerived>& other)
00265 {
00266 internal::transform_construct_from_matrix<OtherDerived,Mode,Dim,HDim>::run(this, other.derived());
00267 return *this;
00268 }
00269
00270 template<int OtherMode>
00271 inline Transform(const Transform<Scalar,Dim,OtherMode>& other)
00272 {
00273
00274
00275 EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(OtherMode==int(Projective), Mode==int(Projective)),
00276 YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION)
00277
00278
00279
00280 EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(OtherMode==int(Affine)||OtherMode==int(AffineCompact), Mode!=int(Isometry)),
00281 YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION)
00282
00283 enum { ModeIsAffineCompact = Mode == int(AffineCompact),
00284 OtherModeIsAffineCompact = OtherMode == int(AffineCompact)
00285 };
00286
00287 if(ModeIsAffineCompact == OtherModeIsAffineCompact)
00288 {
00289
00290
00291
00292 m_matrix.template block<Dim,Dim+1>(0,0) = other.matrix().template block<Dim,Dim+1>(0,0);
00293 makeAffine();
00294 }
00295 else if(OtherModeIsAffineCompact)
00296 {
00297 typedef typename Transform<Scalar,Dim,OtherMode>::MatrixType OtherMatrixType;
00298 internal::transform_construct_from_matrix<OtherMatrixType,Mode,Dim,HDim>::run(this, other.matrix());
00299 }
00300 else
00301 {
00302
00303
00304
00305 linear() = other.linear();
00306 translation() = other.translation();
00307 }
00308 }
00309
00310 template<typename OtherDerived>
00311 Transform(const ReturnByValue<OtherDerived>& other)
00312 {
00313 other.evalTo(*this);
00314 }
00315
00316 template<typename OtherDerived>
00317 Transform& operator=(const ReturnByValue<OtherDerived>& other)
00318 {
00319 other.evalTo(*this);
00320 return *this;
00321 }
00322
00323 #ifdef EIGEN_QT_SUPPORT
00324 inline Transform(const QMatrix& other);
00325 inline Transform& operator=(const QMatrix& other);
00326 inline QMatrix toQMatrix(void) const;
00327 inline Transform(const QTransform& other);
00328 inline Transform& operator=(const QTransform& other);
00329 inline QTransform toQTransform(void) const;
00330 #endif
00331
00332
00333
00334 inline Scalar operator() (Index row, Index col) const { return m_matrix(row,col); }
00335
00336
00337 inline Scalar& operator() (Index row, Index col) { return m_matrix(row,col); }
00338
00339
00340 inline const MatrixType& matrix() const { return m_matrix; }
00341
00342 inline MatrixType& matrix() { return m_matrix; }
00343
00344
00345 inline ConstLinearPart linear() const { return m_matrix.template block<Dim,Dim>(0,0); }
00346
00347 inline LinearPart linear() { return m_matrix.template block<Dim,Dim>(0,0); }
00348
00349
00350 inline ConstAffinePart affine() const { return take_affine_part::run(m_matrix); }
00351
00352 inline AffinePart affine() { return take_affine_part::run(m_matrix); }
00353
00354
00355 inline ConstTranslationPart translation() const { return m_matrix.template block<Dim,1>(0,Dim); }
00356
00357 inline TranslationPart translation() { return m_matrix.template block<Dim,1>(0,Dim); }
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 template<typename OtherDerived>
00372 EIGEN_STRONG_INLINE const typename internal::transform_right_product_impl<Transform, OtherDerived>::ResultType
00373 operator * (const EigenBase<OtherDerived> &other) const
00374 { return internal::transform_right_product_impl<Transform, OtherDerived>::run(*this,other.derived()); }
00375
00376
00377
00378
00379
00380
00381
00382
00383 template<typename OtherDerived> friend
00384 inline const typename internal::transform_left_product_impl<OtherDerived,Mode,_Dim,_Dim+1>::ResultType
00385 operator * (const EigenBase<OtherDerived> &a, const Transform &b)
00386 { return internal::transform_left_product_impl<OtherDerived,Mode,Dim,HDim>::run(a.derived(),b); }
00387
00388
00389
00390
00391
00392
00393
00394 template<typename DiagonalDerived>
00395 inline const TransformTimeDiagonalReturnType
00396 operator * (const DiagonalBase<DiagonalDerived> &b) const
00397 {
00398 TransformTimeDiagonalReturnType res(*this);
00399 res.linear() *= b;
00400 return res;
00401 }
00402
00403
00404
00405
00406
00407
00408
00409 template<typename DiagonalDerived>
00410 friend inline TransformTimeDiagonalReturnType
00411 operator * (const DiagonalBase<DiagonalDerived> &a, const Transform &b)
00412 {
00413 TransformTimeDiagonalReturnType res;
00414 res.linear().noalias() = a*b.linear();
00415 res.translation().noalias() = a*b.translation();
00416 if (Mode!=int(AffineCompact))
00417 res.matrix().row(Dim) = b.matrix().row(Dim);
00418 return res;
00419 }
00420
00421 template<typename OtherDerived>
00422 inline Transform& operator*=(const EigenBase<OtherDerived>& other) { return *this = *this * other; }
00423
00424
00425 inline const Transform operator * (const Transform& other) const
00426 {
00427 return internal::transform_transform_product_impl<Transform,Transform>::run(*this,other);
00428 }
00429
00430
00431 template<int OtherMode>
00432 inline const typename internal::transform_transform_product_impl<
00433 Transform,Transform<Scalar,Dim,OtherMode> >::ResultType
00434 operator * (const Transform<Scalar,Dim,OtherMode>& other) const
00435 {
00436 return internal::transform_transform_product_impl<Transform,Transform<Scalar,Dim,OtherMode> >::run(*this,other);
00437 }
00438
00439
00440 void setIdentity() { m_matrix.setIdentity(); }
00441
00442
00443
00444
00445
00446 static const Transform Identity()
00447 {
00448 return Transform(MatrixType::Identity());
00449 }
00450
00451 template<typename OtherDerived>
00452 inline Transform& scale(const MatrixBase<OtherDerived> &other);
00453
00454 template<typename OtherDerived>
00455 inline Transform& prescale(const MatrixBase<OtherDerived> &other);
00456
00457 inline Transform& scale(Scalar s);
00458 inline Transform& prescale(Scalar s);
00459
00460 template<typename OtherDerived>
00461 inline Transform& translate(const MatrixBase<OtherDerived> &other);
00462
00463 template<typename OtherDerived>
00464 inline Transform& pretranslate(const MatrixBase<OtherDerived> &other);
00465
00466 template<typename RotationType>
00467 inline Transform& rotate(const RotationType& rotation);
00468
00469 template<typename RotationType>
00470 inline Transform& prerotate(const RotationType& rotation);
00471
00472 Transform& shear(Scalar sx, Scalar sy);
00473 Transform& preshear(Scalar sx, Scalar sy);
00474
00475 inline Transform& operator=(const TranslationType& t);
00476 inline Transform& operator*=(const TranslationType& t) { return translate(t.vector()); }
00477 inline Transform operator*(const TranslationType& t) const;
00478
00479 inline Transform& operator=(const UniformScaling<Scalar>& t);
00480 inline Transform& operator*=(const UniformScaling<Scalar>& s) { return scale(s.factor()); }
00481 inline Transform operator*(const UniformScaling<Scalar>& s) const;
00482
00483 inline Transform& operator*=(const DiagonalMatrix<Scalar,Dim>& s) { linear() *= s; return *this; }
00484
00485 template<typename Derived>
00486 inline Transform& operator=(const RotationBase<Derived,Dim>& r);
00487 template<typename Derived>
00488 inline Transform& operator*=(const RotationBase<Derived,Dim>& r) { return rotate(r.toRotationMatrix()); }
00489 template<typename Derived>
00490 inline Transform operator*(const RotationBase<Derived,Dim>& r) const;
00491
00492 LinearMatrixType rotation() const;
00493 template<typename RotationMatrixType, typename ScalingMatrixType>
00494 void computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const;
00495 template<typename ScalingMatrixType, typename RotationMatrixType>
00496 void computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const;
00497
00498 template<typename PositionDerived, typename OrientationType, typename ScaleDerived>
00499 Transform& fromPositionOrientationScale(const MatrixBase<PositionDerived> &position,
00500 const OrientationType& orientation, const MatrixBase<ScaleDerived> &scale);
00501
00502 inline Transform inverse(TransformTraits traits = (TransformTraits)Mode) const;
00503
00504
00505 const Scalar* data() const { return m_matrix.data(); }
00506
00507 Scalar* data() { return m_matrix.data(); }
00508
00509
00510
00511
00512
00513
00514 template<typename NewScalarType>
00515 inline typename internal::cast_return_type<Transform,Transform<NewScalarType,Dim,Mode> >::type cast() const
00516 { return typename internal::cast_return_type<Transform,Transform<NewScalarType,Dim,Mode> >::type(*this); }
00517
00518
00519 template<typename OtherScalarType>
00520 inline explicit Transform(const Transform<OtherScalarType,Dim,Mode>& other)
00521 { m_matrix = other.matrix().template cast<Scalar>(); }
00522
00523
00524
00525
00526
00527 bool isApprox(const Transform& other, typename NumTraits<Scalar>::Real prec = NumTraits<Scalar>::dummy_precision()) const
00528 { return m_matrix.isApprox(other.m_matrix, prec); }
00529
00530
00531
00532 void makeAffine()
00533 {
00534 if(int(Mode)!=int(AffineCompact))
00535 {
00536 matrix().template block<1,Dim>(Dim,0).setZero();
00537 matrix().coeffRef(Dim,Dim) = 1;
00538 }
00539 }
00540
00541
00542
00543
00544
00545 inline Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,Dim> linearExt()
00546 { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,Dim>(0,0); }
00547
00548
00549
00550
00551 inline const Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,Dim> linearExt() const
00552 { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,Dim>(0,0); }
00553
00554
00555
00556
00557
00558 inline Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,1> translationExt()
00559 { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,1>(0,Dim); }
00560
00561
00562
00563
00564 inline const Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,1> translationExt() const
00565 { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,1>(0,Dim); }
00566
00567
00568 #ifdef EIGEN_TRANSFORM_PLUGIN
00569 #include EIGEN_TRANSFORM_PLUGIN
00570 #endif
00571
00572 };
00573
00574
00575 typedef Transform<float,2,Isometry> Isometry2f;
00576
00577 typedef Transform<float,3,Isometry> Isometry3f;
00578
00579 typedef Transform<double,2,Isometry> Isometry2d;
00580
00581 typedef Transform<double,3,Isometry> Isometry3d;
00582
00583
00584 typedef Transform<float,2,Affine> Affine2f;
00585
00586 typedef Transform<float,3,Affine> Affine3f;
00587
00588 typedef Transform<double,2,Affine> Affine2d;
00589
00590 typedef Transform<double,3,Affine> Affine3d;
00591
00592
00593 typedef Transform<float,2,AffineCompact> AffineCompact2f;
00594
00595 typedef Transform<float,3,AffineCompact> AffineCompact3f;
00596
00597 typedef Transform<double,2,AffineCompact> AffineCompact2d;
00598
00599 typedef Transform<double,3,AffineCompact> AffineCompact3d;
00600
00601
00602 typedef Transform<float,2,Projective> Projective2f;
00603
00604 typedef Transform<float,3,Projective> Projective3f;
00605
00606 typedef Transform<double,2,Projective> Projective2d;
00607
00608 typedef Transform<double,3,Projective> Projective3d;
00609
00610 #ifdef EIGEN2_SUPPORT
00611 #include "src/Eigen2Support/Transform.h"
00612 #endif
00613
00614
00615
00616
00617
00618 #ifdef EIGEN_QT_SUPPORT
00619
00620
00621
00622
00623 template<typename Scalar, int Dim, int Mode>
00624 Transform<Scalar,Dim,Mode>::Transform(const QMatrix& other)
00625 {
00626 *this = other;
00627 }
00628
00629
00630
00631
00632
00633 template<typename Scalar, int Dim, int Mode>
00634 Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::operator=(const QMatrix& other)
00635 {
00636 EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00637 m_matrix << other.m11(), other.m21(), other.dx(),
00638 other.m12(), other.m22(), other.dy(),
00639 0, 0, 1;
00640 return *this;
00641 }
00642
00643
00644
00645
00646
00647
00648
00649 template<typename Scalar, int Dim, int Mode>
00650 QMatrix Transform<Scalar,Dim,Mode>::toQMatrix(void) const
00651 {
00652 EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00653 return QMatrix(m_matrix.coeff(0,0), m_matrix.coeff(1,0),
00654 m_matrix.coeff(0,1), m_matrix.coeff(1,1),
00655 m_matrix.coeff(0,2), m_matrix.coeff(1,2));
00656 }
00657
00658
00659
00660
00661
00662 template<typename Scalar, int Dim, int Mode>
00663 Transform<Scalar,Dim,Mode>::Transform(const QTransform& other)
00664 {
00665 *this = other;
00666 }
00667
00668
00669
00670
00671
00672 template<typename Scalar, int Dim, int Mode>
00673 Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::operator=(const QTransform& other)
00674 {
00675 EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00676 m_matrix << other.m11(), other.m21(), other.dx(),
00677 other.m12(), other.m22(), other.dy(),
00678 other.m13(), other.m23(), other.m33();
00679 return *this;
00680 }
00681
00682
00683
00684
00685
00686 template<typename Scalar, int Dim, int Mode>
00687 QTransform Transform<Scalar,Dim,Mode>::toQTransform(void) const
00688 {
00689 EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00690 return QTransform(matrix.coeff(0,0), matrix.coeff(1,0), matrix.coeff(2,0)
00691 matrix.coeff(0,1), matrix.coeff(1,1), matrix.coeff(2,1)
00692 matrix.coeff(0,2), matrix.coeff(1,2), matrix.coeff(2,2));
00693 }
00694 #endif
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704 template<typename Scalar, int Dim, int Mode>
00705 template<typename OtherDerived>
00706 Transform<Scalar,Dim,Mode>&
00707 Transform<Scalar,Dim,Mode>::scale(const MatrixBase<OtherDerived> &other)
00708 {
00709 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
00710 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
00711 linearExt().noalias() = (linearExt() * other.asDiagonal());
00712 return *this;
00713 }
00714
00715
00716
00717
00718
00719 template<typename Scalar, int Dim, int Mode>
00720 inline Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::scale(Scalar s)
00721 {
00722 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
00723 linearExt() *= s;
00724 return *this;
00725 }
00726
00727
00728
00729
00730
00731 template<typename Scalar, int Dim, int Mode>
00732 template<typename OtherDerived>
00733 Transform<Scalar,Dim,Mode>&
00734 Transform<Scalar,Dim,Mode>::prescale(const MatrixBase<OtherDerived> &other)
00735 {
00736 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
00737 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
00738 m_matrix.template block<Dim,HDim>(0,0).noalias() = (other.asDiagonal() * m_matrix.template block<Dim,HDim>(0,0));
00739 return *this;
00740 }
00741
00742
00743
00744
00745
00746 template<typename Scalar, int Dim, int Mode>
00747 inline Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::prescale(Scalar s)
00748 {
00749 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
00750 m_matrix.template topRows<Dim>() *= s;
00751 return *this;
00752 }
00753
00754
00755
00756
00757
00758 template<typename Scalar, int Dim, int Mode>
00759 template<typename OtherDerived>
00760 Transform<Scalar,Dim,Mode>&
00761 Transform<Scalar,Dim,Mode>::translate(const MatrixBase<OtherDerived> &other)
00762 {
00763 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
00764 translationExt() += linearExt() * other;
00765 return *this;
00766 }
00767
00768
00769
00770
00771
00772 template<typename Scalar, int Dim, int Mode>
00773 template<typename OtherDerived>
00774 Transform<Scalar,Dim,Mode>&
00775 Transform<Scalar,Dim,Mode>::pretranslate(const MatrixBase<OtherDerived> &other)
00776 {
00777 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
00778 if(int(Mode)==int(Projective))
00779 affine() += other * m_matrix.row(Dim);
00780 else
00781 translation() += other;
00782 return *this;
00783 }
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802 template<typename Scalar, int Dim, int Mode>
00803 template<typename RotationType>
00804 Transform<Scalar,Dim,Mode>&
00805 Transform<Scalar,Dim,Mode>::rotate(const RotationType& rotation)
00806 {
00807 linearExt() *= internal::toRotationMatrix<Scalar,Dim>(rotation);
00808 return *this;
00809 }
00810
00811
00812
00813
00814
00815
00816
00817
00818 template<typename Scalar, int Dim, int Mode>
00819 template<typename RotationType>
00820 Transform<Scalar,Dim,Mode>&
00821 Transform<Scalar,Dim,Mode>::prerotate(const RotationType& rotation)
00822 {
00823 m_matrix.template block<Dim,HDim>(0,0) = internal::toRotationMatrix<Scalar,Dim>(rotation)
00824 * m_matrix.template block<Dim,HDim>(0,0);
00825 return *this;
00826 }
00827
00828
00829
00830
00831
00832
00833 template<typename Scalar, int Dim, int Mode>
00834 Transform<Scalar,Dim,Mode>&
00835 Transform<Scalar,Dim,Mode>::shear(Scalar sx, Scalar sy)
00836 {
00837 EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00838 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
00839 VectorType tmp = linear().col(0)*sy + linear().col(1);
00840 linear() << linear().col(0) + linear().col(1)*sx, tmp;
00841 return *this;
00842 }
00843
00844
00845
00846
00847
00848
00849 template<typename Scalar, int Dim, int Mode>
00850 Transform<Scalar,Dim,Mode>&
00851 Transform<Scalar,Dim,Mode>::preshear(Scalar sx, Scalar sy)
00852 {
00853 EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
00854 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
00855 m_matrix.template block<Dim,HDim>(0,0) = LinearMatrixType(1, sx, sy, 1) * m_matrix.template block<Dim,HDim>(0,0);
00856 return *this;
00857 }
00858
00859
00860
00861
00862
00863 template<typename Scalar, int Dim, int Mode>
00864 inline Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::operator=(const TranslationType& t)
00865 {
00866 linear().setIdentity();
00867 translation() = t.vector();
00868 makeAffine();
00869 return *this;
00870 }
00871
00872 template<typename Scalar, int Dim, int Mode>
00873 inline Transform<Scalar,Dim,Mode> Transform<Scalar,Dim,Mode>::operator*(const TranslationType& t) const
00874 {
00875 Transform res = *this;
00876 res.translate(t.vector());
00877 return res;
00878 }
00879
00880 template<typename Scalar, int Dim, int Mode>
00881 inline Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::operator=(const UniformScaling<Scalar>& s)
00882 {
00883 m_matrix.setZero();
00884 linear().diagonal().fill(s.factor());
00885 makeAffine();
00886 return *this;
00887 }
00888
00889 template<typename Scalar, int Dim, int Mode>
00890 inline Transform<Scalar,Dim,Mode> Transform<Scalar,Dim,Mode>::operator*(const UniformScaling<Scalar>& s) const
00891 {
00892 Transform res = *this;
00893 res.scale(s.factor());
00894 return res;
00895 }
00896
00897 template<typename Scalar, int Dim, int Mode>
00898 template<typename Derived>
00899 inline Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::operator=(const RotationBase<Derived,Dim>& r)
00900 {
00901 linear() = internal::toRotationMatrix<Scalar,Dim>(r);
00902 translation().setZero();
00903 makeAffine();
00904 return *this;
00905 }
00906
00907 template<typename Scalar, int Dim, int Mode>
00908 template<typename Derived>
00909 inline Transform<Scalar,Dim,Mode> Transform<Scalar,Dim,Mode>::operator*(const RotationBase<Derived,Dim>& r) const
00910 {
00911 Transform res = *this;
00912 res.rotate(r.derived());
00913 return res;
00914 }
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927 template<typename Scalar, int Dim, int Mode>
00928 typename Transform<Scalar,Dim,Mode>::LinearMatrixType
00929 Transform<Scalar,Dim,Mode>::rotation() const
00930 {
00931 LinearMatrixType result;
00932 computeRotationScaling(&result, (LinearMatrixType*)0);
00933 return result;
00934 }
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948 template<typename Scalar, int Dim, int Mode>
00949 template<typename RotationMatrixType, typename ScalingMatrixType>
00950 void Transform<Scalar,Dim,Mode>::computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const
00951 {
00952 JacobiSVD<LinearMatrixType> svd(linear(), ComputeFullU | ComputeFullV);
00953
00954 Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant();
00955 VectorType sv(svd.singularValues());
00956 sv.coeffRef(0) *= x;
00957 if(scaling) scaling->lazyAssign(svd.matrixV() * sv.asDiagonal() * svd.matrixV().adjoint());
00958 if(rotation)
00959 {
00960 LinearMatrixType m(svd.matrixU());
00961 m.col(0) /= x;
00962 rotation->lazyAssign(m * svd.matrixV().adjoint());
00963 }
00964 }
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977 template<typename Scalar, int Dim, int Mode>
00978 template<typename ScalingMatrixType, typename RotationMatrixType>
00979 void Transform<Scalar,Dim,Mode>::computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const
00980 {
00981 JacobiSVD<LinearMatrixType> svd(linear(), ComputeFullU | ComputeFullV);
00982
00983 Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant();
00984 VectorType sv(svd.singularValues());
00985 sv.coeffRef(0) *= x;
00986 if(scaling) scaling->lazyAssign(svd.matrixU() * sv.asDiagonal() * svd.matrixU().adjoint());
00987 if(rotation)
00988 {
00989 LinearMatrixType m(svd.matrixU());
00990 m.col(0) /= x;
00991 rotation->lazyAssign(m * svd.matrixV().adjoint());
00992 }
00993 }
00994
00995
00996
00997
00998 template<typename Scalar, int Dim, int Mode>
00999 template<typename PositionDerived, typename OrientationType, typename ScaleDerived>
01000 Transform<Scalar,Dim,Mode>&
01001 Transform<Scalar,Dim,Mode>::fromPositionOrientationScale(const MatrixBase<PositionDerived> &position,
01002 const OrientationType& orientation, const MatrixBase<ScaleDerived> &scale)
01003 {
01004 linear() = internal::toRotationMatrix<Scalar,Dim>(orientation);
01005 linear() *= scale.asDiagonal();
01006 translation() = position;
01007 makeAffine();
01008 return *this;
01009 }
01010
01011 namespace internal {
01012
01013
01014 template<typename TransformType, int Mode=TransformType::Mode>
01015 struct projective_transform_inverse
01016 {
01017 static inline void run(const TransformType&, TransformType&)
01018 {}
01019 };
01020
01021 template<typename TransformType>
01022 struct projective_transform_inverse<TransformType, Projective>
01023 {
01024 static inline void run(const TransformType& m, TransformType& res)
01025 {
01026 res.matrix() = m.matrix().inverse();
01027 }
01028 };
01029
01030 }
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052 template<typename Scalar, int Dim, int Mode>
01053 Transform<Scalar,Dim,Mode>
01054 Transform<Scalar,Dim,Mode>::inverse(TransformTraits hint) const
01055 {
01056 Transform res;
01057 if (hint == Projective)
01058 {
01059 internal::projective_transform_inverse<Transform>::run(*this, res);
01060 }
01061 else
01062 {
01063 if (hint == Isometry)
01064 {
01065 res.matrix().template topLeftCorner<Dim,Dim>() = linear().transpose();
01066 }
01067 else if(hint&Affine)
01068 {
01069 res.matrix().template topLeftCorner<Dim,Dim>() = linear().inverse();
01070 }
01071 else
01072 {
01073 eigen_assert(false && "Invalid transform traits in Transform::Inverse");
01074 }
01075
01076 res.matrix().template topRightCorner<Dim,1>()
01077 = - res.matrix().template topLeftCorner<Dim,Dim>() * translation();
01078 res.makeAffine();
01079 }
01080 return res;
01081 }
01082
01083 namespace internal {
01084
01085
01086
01087
01088
01089 template<typename TransformType> struct transform_take_affine_part {
01090 typedef typename TransformType::MatrixType MatrixType;
01091 typedef typename TransformType::AffinePart AffinePart;
01092 typedef typename TransformType::ConstAffinePart ConstAffinePart;
01093 static inline AffinePart run(MatrixType& m)
01094 { return m.template block<TransformType::Dim,TransformType::HDim>(0,0); }
01095 static inline ConstAffinePart run(const MatrixType& m)
01096 { return m.template block<TransformType::Dim,TransformType::HDim>(0,0); }
01097 };
01098
01099 template<typename Scalar, int Dim>
01100 struct transform_take_affine_part<Transform<Scalar,Dim,AffineCompact> > {
01101 typedef typename Transform<Scalar,Dim,AffineCompact>::MatrixType MatrixType;
01102 static inline MatrixType& run(MatrixType& m) { return m; }
01103 static inline const MatrixType& run(const MatrixType& m) { return m; }
01104 };
01105
01106
01107
01108
01109
01110 template<typename Other, int Mode, int Dim, int HDim>
01111 struct transform_construct_from_matrix<Other, Mode,Dim,HDim, Dim,Dim>
01112 {
01113 static inline void run(Transform<typename Other::Scalar,Dim,Mode> *transform, const Other& other)
01114 {
01115 transform->linear() = other;
01116 transform->translation().setZero();
01117 transform->makeAffine();
01118 }
01119 };
01120
01121 template<typename Other, int Mode, int Dim, int HDim>
01122 struct transform_construct_from_matrix<Other, Mode,Dim,HDim, Dim,HDim>
01123 {
01124 static inline void run(Transform<typename Other::Scalar,Dim,Mode> *transform, const Other& other)
01125 {
01126 transform->affine() = other;
01127 transform->makeAffine();
01128 }
01129 };
01130
01131 template<typename Other, int Mode, int Dim, int HDim>
01132 struct transform_construct_from_matrix<Other, Mode,Dim,HDim, HDim,HDim>
01133 {
01134 static inline void run(Transform<typename Other::Scalar,Dim,Mode> *transform, const Other& other)
01135 { transform->matrix() = other; }
01136 };
01137
01138 template<typename Other, int Dim, int HDim>
01139 struct transform_construct_from_matrix<Other, AffineCompact,Dim,HDim, HDim,HDim>
01140 {
01141 static inline void run(Transform<typename Other::Scalar,Dim,AffineCompact> *transform, const Other& other)
01142 { transform->matrix() = other.template block<Dim,HDim>(0,0); }
01143 };
01144
01145
01146
01147
01148
01149 template<int LhsMode,int RhsMode>
01150 struct transform_product_result
01151 {
01152 enum
01153 {
01154 Mode =
01155 (LhsMode == (int)Projective || RhsMode == (int)Projective ) ? Projective :
01156 (LhsMode == (int)Affine || RhsMode == (int)Affine ) ? Affine :
01157 (LhsMode == (int)AffineCompact || RhsMode == (int)AffineCompact ) ? AffineCompact :
01158 (LhsMode == (int)Isometry || RhsMode == (int)Isometry ) ? Isometry : Projective
01159 };
01160 };
01161
01162 template< typename TransformType, typename MatrixType >
01163 struct transform_right_product_impl< TransformType, MatrixType, true >
01164 {
01165 typedef typename MatrixType::PlainObject ResultType;
01166
01167 EIGEN_STRONG_INLINE static ResultType run(const TransformType& T, const MatrixType& other)
01168 {
01169 return T.matrix() * other;
01170 }
01171 };
01172
01173 template< typename TransformType, typename MatrixType >
01174 struct transform_right_product_impl< TransformType, MatrixType, false >
01175 {
01176 enum {
01177 Dim = TransformType::Dim,
01178 HDim = TransformType::HDim,
01179 OtherRows = MatrixType::RowsAtCompileTime,
01180 OtherCols = MatrixType::ColsAtCompileTime
01181 };
01182
01183 typedef typename MatrixType::PlainObject ResultType;
01184
01185 EIGEN_STRONG_INLINE static ResultType run(const TransformType& T, const MatrixType& other)
01186 {
01187 EIGEN_STATIC_ASSERT(OtherRows==Dim || OtherRows==HDim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);
01188
01189 typedef Block<ResultType, Dim, OtherCols> TopLeftLhs;
01190 typedef Block<const MatrixType, Dim, OtherCols> TopLeftRhs;
01191
01192 ResultType res(other.rows(),other.cols());
01193
01194 TopLeftLhs(res, 0, 0, Dim, other.cols()) =
01195 ( T.linear() * TopLeftRhs(other, 0, 0, Dim, other.cols()) ).colwise() +
01196 T.translation();
01197
01198
01199 if (OtherRows==HDim)
01200 res.row(other.rows()) = other.row(other.rows());
01201
01202 return res;
01203 }
01204 };
01205
01206
01207
01208
01209
01210
01211 template<typename Other,int Mode, int Dim, int HDim>
01212 struct transform_left_product_impl<Other,Mode,Dim,HDim, HDim,HDim>
01213 {
01214 typedef Transform<typename Other::Scalar,Dim,Mode> TransformType;
01215 typedef typename TransformType::MatrixType MatrixType;
01216 typedef Transform<typename Other::Scalar,Dim,Projective> ResultType;
01217 static ResultType run(const Other& other,const TransformType& tr)
01218 { return ResultType(other * tr.matrix()); }
01219 };
01220
01221
01222 template<typename Other, int Dim, int HDim>
01223 struct transform_left_product_impl<Other,AffineCompact,Dim,HDim, HDim,HDim>
01224 {
01225 typedef Transform<typename Other::Scalar,Dim,AffineCompact> TransformType;
01226 typedef typename TransformType::MatrixType MatrixType;
01227 typedef Transform<typename Other::Scalar,Dim,Projective> ResultType;
01228 static ResultType run(const Other& other,const TransformType& tr)
01229 {
01230 ResultType res;
01231 res.matrix().noalias() = other.template block<HDim,Dim>(0,0) * tr.matrix();
01232 res.matrix().col(Dim) += other.col(Dim);
01233 return res;
01234 }
01235 };
01236
01237
01238 template<typename Other,int Mode, int Dim, int HDim>
01239 struct transform_left_product_impl<Other,Mode,Dim,HDim, Dim,HDim>
01240 {
01241 typedef Transform<typename Other::Scalar,Dim,Mode> TransformType;
01242 typedef typename TransformType::MatrixType MatrixType;
01243 typedef TransformType ResultType;
01244 static ResultType run(const Other& other,const TransformType& tr)
01245 {
01246 ResultType res;
01247 res.affine().noalias() = other * tr.matrix();
01248 res.matrix().row(Dim) = tr.matrix().row(Dim);
01249 return res;
01250 }
01251 };
01252
01253
01254 template<typename Other, int Dim, int HDim>
01255 struct transform_left_product_impl<Other,AffineCompact,Dim,HDim, Dim,HDim>
01256 {
01257 typedef Transform<typename Other::Scalar,Dim,AffineCompact> TransformType;
01258 typedef typename TransformType::MatrixType MatrixType;
01259 typedef TransformType ResultType;
01260 static ResultType run(const Other& other,const TransformType& tr)
01261 {
01262 ResultType res;
01263 res.matrix().noalias() = other.template block<Dim,Dim>(0,0) * tr.matrix();
01264 res.translation() += other.col(Dim);
01265 return res;
01266 }
01267 };
01268
01269
01270 template<typename Other,int Mode, int Dim, int HDim>
01271 struct transform_left_product_impl<Other,Mode,Dim,HDim, Dim,Dim>
01272 {
01273 typedef Transform<typename Other::Scalar,Dim,Mode> TransformType;
01274 typedef typename TransformType::MatrixType MatrixType;
01275 typedef TransformType ResultType;
01276 static ResultType run(const Other& other, const TransformType& tr)
01277 {
01278 TransformType res;
01279 if(Mode!=int(AffineCompact))
01280 res.matrix().row(Dim) = tr.matrix().row(Dim);
01281 res.matrix().template topRows<Dim>().noalias()
01282 = other * tr.matrix().template topRows<Dim>();
01283 return res;
01284 }
01285 };
01286
01287
01288
01289
01290
01291 template<typename Scalar, int Dim, int LhsMode, int RhsMode>
01292 struct transform_transform_product_impl<Transform<Scalar,Dim,LhsMode>,Transform<Scalar,Dim,RhsMode>,false >
01293 {
01294 enum { ResultMode = transform_product_result<LhsMode,RhsMode>::Mode };
01295 typedef Transform<Scalar,Dim,LhsMode> Lhs;
01296 typedef Transform<Scalar,Dim,RhsMode> Rhs;
01297 typedef Transform<Scalar,Dim,ResultMode> ResultType;
01298 static ResultType run(const Lhs& lhs, const Rhs& rhs)
01299 {
01300 ResultType res;
01301 res.linear() = lhs.linear() * rhs.linear();
01302 res.translation() = lhs.linear() * rhs.translation() + lhs.translation();
01303 res.makeAffine();
01304 return res;
01305 }
01306 };
01307
01308 template<typename Scalar, int Dim, int LhsMode, int RhsMode>
01309 struct transform_transform_product_impl<Transform<Scalar,Dim,LhsMode>,Transform<Scalar,Dim,RhsMode>,true >
01310 {
01311 typedef Transform<Scalar,Dim,LhsMode> Lhs;
01312 typedef Transform<Scalar,Dim,RhsMode> Rhs;
01313 typedef Transform<Scalar,Dim,Projective> ResultType;
01314 static ResultType run(const Lhs& lhs, const Rhs& rhs)
01315 {
01316 return ResultType( lhs.matrix() * rhs.matrix() );
01317 }
01318 };
01319
01320 }
01321
01322 #endif // EIGEN_TRANSFORM_H