Warning, file /include/eigen3/Eigen/src/Geometry/Transform.h was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef EIGEN_TRANSFORM_H
0013 #define EIGEN_TRANSFORM_H
0014
0015 namespace Eigen {
0016
0017 namespace internal {
0018
0019 template<typename Transform>
0020 struct transform_traits
0021 {
0022 enum
0023 {
0024 Dim = Transform::Dim,
0025 HDim = Transform::HDim,
0026 Mode = Transform::Mode,
0027 IsProjective = (int(Mode)==int(Projective))
0028 };
0029 };
0030
0031 template< typename TransformType,
0032 typename MatrixType,
0033 int Case = transform_traits<TransformType>::IsProjective ? 0
0034 : int(MatrixType::RowsAtCompileTime) == int(transform_traits<TransformType>::HDim) ? 1
0035 : 2,
0036 int RhsCols = MatrixType::ColsAtCompileTime>
0037 struct transform_right_product_impl;
0038
0039 template< typename Other,
0040 int Mode,
0041 int Options,
0042 int Dim,
0043 int HDim,
0044 int OtherRows=Other::RowsAtCompileTime,
0045 int OtherCols=Other::ColsAtCompileTime>
0046 struct transform_left_product_impl;
0047
0048 template< typename Lhs,
0049 typename Rhs,
0050 bool AnyProjective =
0051 transform_traits<Lhs>::IsProjective ||
0052 transform_traits<Rhs>::IsProjective>
0053 struct transform_transform_product_impl;
0054
0055 template< typename Other,
0056 int Mode,
0057 int Options,
0058 int Dim,
0059 int HDim,
0060 int OtherRows=Other::RowsAtCompileTime,
0061 int OtherCols=Other::ColsAtCompileTime>
0062 struct transform_construct_from_matrix;
0063
0064 template<typename TransformType> struct transform_take_affine_part;
0065
0066 template<typename _Scalar, int _Dim, int _Mode, int _Options>
0067 struct traits<Transform<_Scalar,_Dim,_Mode,_Options> >
0068 {
0069 typedef _Scalar Scalar;
0070 typedef Eigen::Index StorageIndex;
0071 typedef Dense StorageKind;
0072 enum {
0073 Dim1 = _Dim==Dynamic ? _Dim : _Dim + 1,
0074 RowsAtCompileTime = _Mode==Projective ? Dim1 : _Dim,
0075 ColsAtCompileTime = Dim1,
0076 MaxRowsAtCompileTime = RowsAtCompileTime,
0077 MaxColsAtCompileTime = ColsAtCompileTime,
0078 Flags = 0
0079 };
0080 };
0081
0082 template<int Mode> struct transform_make_affine;
0083
0084 }
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203 template<typename _Scalar, int _Dim, int _Mode, int _Options>
0204 class Transform
0205 {
0206 public:
0207 EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_Dim==Dynamic ? Dynamic : (_Dim+1)*(_Dim+1))
0208 enum {
0209 Mode = _Mode,
0210 Options = _Options,
0211 Dim = _Dim,
0212 HDim = _Dim+1,
0213 Rows = int(Mode)==(AffineCompact) ? Dim : HDim
0214 };
0215
0216 typedef _Scalar Scalar;
0217 typedef Eigen::Index StorageIndex;
0218 typedef Eigen::Index Index;
0219
0220 typedef typename internal::make_proper_matrix_type<Scalar,Rows,HDim,Options>::type MatrixType;
0221
0222 typedef const MatrixType ConstMatrixType;
0223
0224 typedef Matrix<Scalar,Dim,Dim,Options> LinearMatrixType;
0225
0226 typedef Block<MatrixType,Dim,Dim,int(Mode)==(AffineCompact) && (int(Options)&RowMajor)==0> LinearPart;
0227
0228 typedef const Block<ConstMatrixType,Dim,Dim,int(Mode)==(AffineCompact) && (int(Options)&RowMajor)==0> ConstLinearPart;
0229
0230 typedef typename internal::conditional<int(Mode)==int(AffineCompact),
0231 MatrixType&,
0232 Block<MatrixType,Dim,HDim> >::type AffinePart;
0233
0234 typedef typename internal::conditional<int(Mode)==int(AffineCompact),
0235 const MatrixType&,
0236 const Block<const MatrixType,Dim,HDim> >::type ConstAffinePart;
0237
0238 typedef Matrix<Scalar,Dim,1> VectorType;
0239
0240 typedef Block<MatrixType,Dim,1,!(internal::traits<MatrixType>::Flags & RowMajorBit)> TranslationPart;
0241
0242 typedef const Block<ConstMatrixType,Dim,1,!(internal::traits<MatrixType>::Flags & RowMajorBit)> ConstTranslationPart;
0243
0244 typedef Translation<Scalar,Dim> TranslationType;
0245
0246
0247 enum { TransformTimeDiagonalMode = ((Mode==int(Isometry))?Affine:int(Mode)) };
0248
0249 typedef Transform<Scalar,Dim,TransformTimeDiagonalMode> TransformTimeDiagonalReturnType;
0250
0251 protected:
0252
0253 MatrixType m_matrix;
0254
0255 public:
0256
0257
0258
0259 EIGEN_DEVICE_FUNC inline Transform()
0260 {
0261 check_template_params();
0262 internal::transform_make_affine<(int(Mode)==Affine || int(Mode)==Isometry) ? Affine : AffineCompact>::run(m_matrix);
0263 }
0264
0265 EIGEN_DEVICE_FUNC inline explicit Transform(const TranslationType& t)
0266 {
0267 check_template_params();
0268 *this = t;
0269 }
0270 EIGEN_DEVICE_FUNC inline explicit Transform(const UniformScaling<Scalar>& s)
0271 {
0272 check_template_params();
0273 *this = s;
0274 }
0275 template<typename Derived>
0276 EIGEN_DEVICE_FUNC inline explicit Transform(const RotationBase<Derived, Dim>& r)
0277 {
0278 check_template_params();
0279 *this = r;
0280 }
0281
0282 typedef internal::transform_take_affine_part<Transform> take_affine_part;
0283
0284
0285 template<typename OtherDerived>
0286 EIGEN_DEVICE_FUNC inline explicit Transform(const EigenBase<OtherDerived>& other)
0287 {
0288 EIGEN_STATIC_ASSERT((internal::is_same<Scalar,typename OtherDerived::Scalar>::value),
0289 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY);
0290
0291 check_template_params();
0292 internal::transform_construct_from_matrix<OtherDerived,Mode,Options,Dim,HDim>::run(this, other.derived());
0293 }
0294
0295
0296 template<typename OtherDerived>
0297 EIGEN_DEVICE_FUNC inline Transform& operator=(const EigenBase<OtherDerived>& other)
0298 {
0299 EIGEN_STATIC_ASSERT((internal::is_same<Scalar,typename OtherDerived::Scalar>::value),
0300 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY);
0301
0302 internal::transform_construct_from_matrix<OtherDerived,Mode,Options,Dim,HDim>::run(this, other.derived());
0303 return *this;
0304 }
0305
0306 template<int OtherOptions>
0307 EIGEN_DEVICE_FUNC inline Transform(const Transform<Scalar,Dim,Mode,OtherOptions>& other)
0308 {
0309 check_template_params();
0310
0311 m_matrix = other.matrix();
0312 }
0313
0314 template<int OtherMode,int OtherOptions>
0315 EIGEN_DEVICE_FUNC inline Transform(const Transform<Scalar,Dim,OtherMode,OtherOptions>& other)
0316 {
0317 check_template_params();
0318
0319
0320 EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(OtherMode==int(Projective), Mode==int(Projective)),
0321 YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION)
0322
0323
0324
0325 EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(OtherMode==int(Affine)||OtherMode==int(AffineCompact), Mode!=int(Isometry)),
0326 YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION)
0327
0328 enum { ModeIsAffineCompact = Mode == int(AffineCompact),
0329 OtherModeIsAffineCompact = OtherMode == int(AffineCompact)
0330 };
0331
0332 if(EIGEN_CONST_CONDITIONAL(ModeIsAffineCompact == OtherModeIsAffineCompact))
0333 {
0334
0335
0336
0337 m_matrix.template block<Dim,Dim+1>(0,0) = other.matrix().template block<Dim,Dim+1>(0,0);
0338 makeAffine();
0339 }
0340 else if(EIGEN_CONST_CONDITIONAL(OtherModeIsAffineCompact))
0341 {
0342 typedef typename Transform<Scalar,Dim,OtherMode,OtherOptions>::MatrixType OtherMatrixType;
0343 internal::transform_construct_from_matrix<OtherMatrixType,Mode,Options,Dim,HDim>::run(this, other.matrix());
0344 }
0345 else
0346 {
0347
0348
0349
0350 linear() = other.linear();
0351 translation() = other.translation();
0352 }
0353 }
0354
0355 template<typename OtherDerived>
0356 EIGEN_DEVICE_FUNC Transform(const ReturnByValue<OtherDerived>& other)
0357 {
0358 check_template_params();
0359 other.evalTo(*this);
0360 }
0361
0362 template<typename OtherDerived>
0363 EIGEN_DEVICE_FUNC Transform& operator=(const ReturnByValue<OtherDerived>& other)
0364 {
0365 other.evalTo(*this);
0366 return *this;
0367 }
0368
0369 #ifdef EIGEN_QT_SUPPORT
0370 inline Transform(const QMatrix& other);
0371 inline Transform& operator=(const QMatrix& other);
0372 inline QMatrix toQMatrix(void) const;
0373 inline Transform(const QTransform& other);
0374 inline Transform& operator=(const QTransform& other);
0375 inline QTransform toQTransform(void) const;
0376 #endif
0377
0378 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return int(Mode)==int(Projective) ? m_matrix.cols() : (m_matrix.cols()-1); }
0379 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_matrix.cols(); }
0380
0381
0382
0383 EIGEN_DEVICE_FUNC inline Scalar operator() (Index row, Index col) const { return m_matrix(row,col); }
0384
0385
0386 EIGEN_DEVICE_FUNC inline Scalar& operator() (Index row, Index col) { return m_matrix(row,col); }
0387
0388
0389 EIGEN_DEVICE_FUNC inline const MatrixType& matrix() const { return m_matrix; }
0390
0391 EIGEN_DEVICE_FUNC inline MatrixType& matrix() { return m_matrix; }
0392
0393
0394 EIGEN_DEVICE_FUNC inline ConstLinearPart linear() const { return ConstLinearPart(m_matrix,0,0); }
0395
0396 EIGEN_DEVICE_FUNC inline LinearPart linear() { return LinearPart(m_matrix,0,0); }
0397
0398
0399 EIGEN_DEVICE_FUNC inline ConstAffinePart affine() const { return take_affine_part::run(m_matrix); }
0400
0401 EIGEN_DEVICE_FUNC inline AffinePart affine() { return take_affine_part::run(m_matrix); }
0402
0403
0404 EIGEN_DEVICE_FUNC inline ConstTranslationPart translation() const { return ConstTranslationPart(m_matrix,0,Dim); }
0405
0406 EIGEN_DEVICE_FUNC inline TranslationPart translation() { return TranslationPart(m_matrix,0,Dim); }
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433 template<typename OtherDerived>
0434 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename internal::transform_right_product_impl<Transform, OtherDerived>::ResultType
0435 operator * (const EigenBase<OtherDerived> &other) const
0436 { return internal::transform_right_product_impl<Transform, OtherDerived>::run(*this,other.derived()); }
0437
0438
0439
0440
0441
0442
0443
0444
0445 template<typename OtherDerived> friend
0446 EIGEN_DEVICE_FUNC inline const typename internal::transform_left_product_impl<OtherDerived,Mode,Options,_Dim,_Dim+1>::ResultType
0447 operator * (const EigenBase<OtherDerived> &a, const Transform &b)
0448 { return internal::transform_left_product_impl<OtherDerived,Mode,Options,Dim,HDim>::run(a.derived(),b); }
0449
0450
0451
0452
0453
0454
0455
0456 template<typename DiagonalDerived>
0457 EIGEN_DEVICE_FUNC inline const TransformTimeDiagonalReturnType
0458 operator * (const DiagonalBase<DiagonalDerived> &b) const
0459 {
0460 TransformTimeDiagonalReturnType res(*this);
0461 res.linearExt() *= b;
0462 return res;
0463 }
0464
0465
0466
0467
0468
0469
0470
0471 template<typename DiagonalDerived>
0472 EIGEN_DEVICE_FUNC friend inline TransformTimeDiagonalReturnType
0473 operator * (const DiagonalBase<DiagonalDerived> &a, const Transform &b)
0474 {
0475 TransformTimeDiagonalReturnType res;
0476 res.linear().noalias() = a*b.linear();
0477 res.translation().noalias() = a*b.translation();
0478 if (EIGEN_CONST_CONDITIONAL(Mode!=int(AffineCompact)))
0479 res.matrix().row(Dim) = b.matrix().row(Dim);
0480 return res;
0481 }
0482
0483 template<typename OtherDerived>
0484 EIGEN_DEVICE_FUNC inline Transform& operator*=(const EigenBase<OtherDerived>& other) { return *this = *this * other; }
0485
0486
0487 EIGEN_DEVICE_FUNC inline const Transform operator * (const Transform& other) const
0488 {
0489 return internal::transform_transform_product_impl<Transform,Transform>::run(*this,other);
0490 }
0491
0492 #if EIGEN_COMP_ICC
0493 private:
0494
0495
0496
0497
0498
0499
0500
0501 template<int OtherMode,int OtherOptions> struct icc_11_workaround
0502 {
0503 typedef internal::transform_transform_product_impl<Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> > ProductType;
0504 typedef typename ProductType::ResultType ResultType;
0505 };
0506
0507 public:
0508
0509 template<int OtherMode,int OtherOptions>
0510 inline typename icc_11_workaround<OtherMode,OtherOptions>::ResultType
0511 operator * (const Transform<Scalar,Dim,OtherMode,OtherOptions>& other) const
0512 {
0513 typedef typename icc_11_workaround<OtherMode,OtherOptions>::ProductType ProductType;
0514 return ProductType::run(*this,other);
0515 }
0516 #else
0517
0518 template<int OtherMode,int OtherOptions>
0519 EIGEN_DEVICE_FUNC inline typename internal::transform_transform_product_impl<Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> >::ResultType
0520 operator * (const Transform<Scalar,Dim,OtherMode,OtherOptions>& other) const
0521 {
0522 return internal::transform_transform_product_impl<Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> >::run(*this,other);
0523 }
0524 #endif
0525
0526
0527 EIGEN_DEVICE_FUNC void setIdentity() { m_matrix.setIdentity(); }
0528
0529
0530
0531
0532
0533 EIGEN_DEVICE_FUNC static const Transform Identity()
0534 {
0535 return Transform(MatrixType::Identity());
0536 }
0537
0538 template<typename OtherDerived>
0539 EIGEN_DEVICE_FUNC
0540 inline Transform& scale(const MatrixBase<OtherDerived> &other);
0541
0542 template<typename OtherDerived>
0543 EIGEN_DEVICE_FUNC
0544 inline Transform& prescale(const MatrixBase<OtherDerived> &other);
0545
0546 EIGEN_DEVICE_FUNC inline Transform& scale(const Scalar& s);
0547 EIGEN_DEVICE_FUNC inline Transform& prescale(const Scalar& s);
0548
0549 template<typename OtherDerived>
0550 EIGEN_DEVICE_FUNC
0551 inline Transform& translate(const MatrixBase<OtherDerived> &other);
0552
0553 template<typename OtherDerived>
0554 EIGEN_DEVICE_FUNC
0555 inline Transform& pretranslate(const MatrixBase<OtherDerived> &other);
0556
0557 template<typename RotationType>
0558 EIGEN_DEVICE_FUNC
0559 inline Transform& rotate(const RotationType& rotation);
0560
0561 template<typename RotationType>
0562 EIGEN_DEVICE_FUNC
0563 inline Transform& prerotate(const RotationType& rotation);
0564
0565 EIGEN_DEVICE_FUNC Transform& shear(const Scalar& sx, const Scalar& sy);
0566 EIGEN_DEVICE_FUNC Transform& preshear(const Scalar& sx, const Scalar& sy);
0567
0568 EIGEN_DEVICE_FUNC inline Transform& operator=(const TranslationType& t);
0569
0570 EIGEN_DEVICE_FUNC
0571 inline Transform& operator*=(const TranslationType& t) { return translate(t.vector()); }
0572
0573 EIGEN_DEVICE_FUNC inline Transform operator*(const TranslationType& t) const;
0574
0575 EIGEN_DEVICE_FUNC
0576 inline Transform& operator=(const UniformScaling<Scalar>& t);
0577
0578 EIGEN_DEVICE_FUNC
0579 inline Transform& operator*=(const UniformScaling<Scalar>& s) { return scale(s.factor()); }
0580
0581 EIGEN_DEVICE_FUNC
0582 inline TransformTimeDiagonalReturnType operator*(const UniformScaling<Scalar>& s) const
0583 {
0584 TransformTimeDiagonalReturnType res = *this;
0585 res.scale(s.factor());
0586 return res;
0587 }
0588
0589 EIGEN_DEVICE_FUNC
0590 inline Transform& operator*=(const DiagonalMatrix<Scalar,Dim>& s) { linearExt() *= s; return *this; }
0591
0592 template<typename Derived>
0593 EIGEN_DEVICE_FUNC inline Transform& operator=(const RotationBase<Derived,Dim>& r);
0594 template<typename Derived>
0595 EIGEN_DEVICE_FUNC inline Transform& operator*=(const RotationBase<Derived,Dim>& r) { return rotate(r.toRotationMatrix()); }
0596 template<typename Derived>
0597 EIGEN_DEVICE_FUNC inline Transform operator*(const RotationBase<Derived,Dim>& r) const;
0598
0599 typedef typename internal::conditional<int(Mode)==Isometry,ConstLinearPart,const LinearMatrixType>::type RotationReturnType;
0600 EIGEN_DEVICE_FUNC RotationReturnType rotation() const;
0601
0602 template<typename RotationMatrixType, typename ScalingMatrixType>
0603 EIGEN_DEVICE_FUNC
0604 void computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const;
0605 template<typename ScalingMatrixType, typename RotationMatrixType>
0606 EIGEN_DEVICE_FUNC
0607 void computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const;
0608
0609 template<typename PositionDerived, typename OrientationType, typename ScaleDerived>
0610 EIGEN_DEVICE_FUNC
0611 Transform& fromPositionOrientationScale(const MatrixBase<PositionDerived> &position,
0612 const OrientationType& orientation, const MatrixBase<ScaleDerived> &scale);
0613
0614 EIGEN_DEVICE_FUNC
0615 inline Transform inverse(TransformTraits traits = (TransformTraits)Mode) const;
0616
0617
0618 EIGEN_DEVICE_FUNC const Scalar* data() const { return m_matrix.data(); }
0619
0620 EIGEN_DEVICE_FUNC Scalar* data() { return m_matrix.data(); }
0621
0622
0623
0624
0625
0626
0627 template<typename NewScalarType>
0628 EIGEN_DEVICE_FUNC inline typename internal::cast_return_type<Transform,Transform<NewScalarType,Dim,Mode,Options> >::type cast() const
0629 { return typename internal::cast_return_type<Transform,Transform<NewScalarType,Dim,Mode,Options> >::type(*this); }
0630
0631
0632 template<typename OtherScalarType>
0633 EIGEN_DEVICE_FUNC inline explicit Transform(const Transform<OtherScalarType,Dim,Mode,Options>& other)
0634 {
0635 check_template_params();
0636 m_matrix = other.matrix().template cast<Scalar>();
0637 }
0638
0639
0640
0641
0642
0643 EIGEN_DEVICE_FUNC bool isApprox(const Transform& other, const typename NumTraits<Scalar>::Real& prec = NumTraits<Scalar>::dummy_precision()) const
0644 { return m_matrix.isApprox(other.m_matrix, prec); }
0645
0646
0647
0648 EIGEN_DEVICE_FUNC void makeAffine()
0649 {
0650 internal::transform_make_affine<int(Mode)>::run(m_matrix);
0651 }
0652
0653
0654
0655
0656
0657 EIGEN_DEVICE_FUNC inline Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,Dim> linearExt()
0658 { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,Dim>(0,0); }
0659
0660
0661
0662
0663 EIGEN_DEVICE_FUNC inline const Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,Dim> linearExt() const
0664 { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,Dim>(0,0); }
0665
0666
0667
0668
0669
0670 EIGEN_DEVICE_FUNC inline Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,1> translationExt()
0671 { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,1>(0,Dim); }
0672
0673
0674
0675
0676 EIGEN_DEVICE_FUNC inline const Block<MatrixType,int(Mode)==int(Projective)?HDim:Dim,1> translationExt() const
0677 { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,1>(0,Dim); }
0678
0679
0680 #ifdef EIGEN_TRANSFORM_PLUGIN
0681 #include EIGEN_TRANSFORM_PLUGIN
0682 #endif
0683
0684 protected:
0685 #ifndef EIGEN_PARSED_BY_DOXYGEN
0686 EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void check_template_params()
0687 {
0688 EIGEN_STATIC_ASSERT((Options & (DontAlign|RowMajor)) == Options, INVALID_MATRIX_TEMPLATE_PARAMETERS)
0689 }
0690 #endif
0691
0692 };
0693
0694
0695 typedef Transform<float,2,Isometry> Isometry2f;
0696
0697 typedef Transform<float,3,Isometry> Isometry3f;
0698
0699 typedef Transform<double,2,Isometry> Isometry2d;
0700
0701 typedef Transform<double,3,Isometry> Isometry3d;
0702
0703
0704 typedef Transform<float,2,Affine> Affine2f;
0705
0706 typedef Transform<float,3,Affine> Affine3f;
0707
0708 typedef Transform<double,2,Affine> Affine2d;
0709
0710 typedef Transform<double,3,Affine> Affine3d;
0711
0712
0713 typedef Transform<float,2,AffineCompact> AffineCompact2f;
0714
0715 typedef Transform<float,3,AffineCompact> AffineCompact3f;
0716
0717 typedef Transform<double,2,AffineCompact> AffineCompact2d;
0718
0719 typedef Transform<double,3,AffineCompact> AffineCompact3d;
0720
0721
0722 typedef Transform<float,2,Projective> Projective2f;
0723
0724 typedef Transform<float,3,Projective> Projective3f;
0725
0726 typedef Transform<double,2,Projective> Projective2d;
0727
0728 typedef Transform<double,3,Projective> Projective3d;
0729
0730
0731
0732
0733
0734 #ifdef EIGEN_QT_SUPPORT
0735
0736
0737
0738
0739 template<typename Scalar, int Dim, int Mode,int Options>
0740 Transform<Scalar,Dim,Mode,Options>::Transform(const QMatrix& other)
0741 {
0742 check_template_params();
0743 *this = other;
0744 }
0745
0746
0747
0748
0749
0750 template<typename Scalar, int Dim, int Mode,int Options>
0751 Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const QMatrix& other)
0752 {
0753 EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
0754 if (EIGEN_CONST_CONDITIONAL(Mode == int(AffineCompact)))
0755 m_matrix << other.m11(), other.m21(), other.dx(),
0756 other.m12(), other.m22(), other.dy();
0757 else
0758 m_matrix << other.m11(), other.m21(), other.dx(),
0759 other.m12(), other.m22(), other.dy(),
0760 0, 0, 1;
0761 return *this;
0762 }
0763
0764
0765
0766
0767
0768
0769
0770 template<typename Scalar, int Dim, int Mode, int Options>
0771 QMatrix Transform<Scalar,Dim,Mode,Options>::toQMatrix(void) const
0772 {
0773 check_template_params();
0774 EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
0775 return QMatrix(m_matrix.coeff(0,0), m_matrix.coeff(1,0),
0776 m_matrix.coeff(0,1), m_matrix.coeff(1,1),
0777 m_matrix.coeff(0,2), m_matrix.coeff(1,2));
0778 }
0779
0780
0781
0782
0783
0784 template<typename Scalar, int Dim, int Mode,int Options>
0785 Transform<Scalar,Dim,Mode,Options>::Transform(const QTransform& other)
0786 {
0787 check_template_params();
0788 *this = other;
0789 }
0790
0791
0792
0793
0794
0795 template<typename Scalar, int Dim, int Mode, int Options>
0796 Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const QTransform& other)
0797 {
0798 check_template_params();
0799 EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
0800 if (EIGEN_CONST_CONDITIONAL(Mode == int(AffineCompact)))
0801 m_matrix << other.m11(), other.m21(), other.dx(),
0802 other.m12(), other.m22(), other.dy();
0803 else
0804 m_matrix << other.m11(), other.m21(), other.dx(),
0805 other.m12(), other.m22(), other.dy(),
0806 other.m13(), other.m23(), other.m33();
0807 return *this;
0808 }
0809
0810
0811
0812
0813
0814 template<typename Scalar, int Dim, int Mode, int Options>
0815 QTransform Transform<Scalar,Dim,Mode,Options>::toQTransform(void) const
0816 {
0817 EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
0818 if (EIGEN_CONST_CONDITIONAL(Mode == int(AffineCompact)))
0819 return QTransform(m_matrix.coeff(0,0), m_matrix.coeff(1,0),
0820 m_matrix.coeff(0,1), m_matrix.coeff(1,1),
0821 m_matrix.coeff(0,2), m_matrix.coeff(1,2));
0822 else
0823 return QTransform(m_matrix.coeff(0,0), m_matrix.coeff(1,0), m_matrix.coeff(2,0),
0824 m_matrix.coeff(0,1), m_matrix.coeff(1,1), m_matrix.coeff(2,1),
0825 m_matrix.coeff(0,2), m_matrix.coeff(1,2), m_matrix.coeff(2,2));
0826 }
0827 #endif
0828
0829
0830
0831
0832
0833
0834
0835
0836
0837 template<typename Scalar, int Dim, int Mode, int Options>
0838 template<typename OtherDerived>
0839 EIGEN_DEVICE_FUNC Transform<Scalar,Dim,Mode,Options>&
0840 Transform<Scalar,Dim,Mode,Options>::scale(const MatrixBase<OtherDerived> &other)
0841 {
0842 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
0843 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
0844 linearExt().noalias() = (linearExt() * other.asDiagonal());
0845 return *this;
0846 }
0847
0848
0849
0850
0851
0852 template<typename Scalar, int Dim, int Mode, int Options>
0853 EIGEN_DEVICE_FUNC inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::scale(const Scalar& s)
0854 {
0855 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
0856 linearExt() *= s;
0857 return *this;
0858 }
0859
0860
0861
0862
0863
0864 template<typename Scalar, int Dim, int Mode, int Options>
0865 template<typename OtherDerived>
0866 EIGEN_DEVICE_FUNC Transform<Scalar,Dim,Mode,Options>&
0867 Transform<Scalar,Dim,Mode,Options>::prescale(const MatrixBase<OtherDerived> &other)
0868 {
0869 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
0870 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
0871 affine().noalias() = (other.asDiagonal() * affine());
0872 return *this;
0873 }
0874
0875
0876
0877
0878
0879 template<typename Scalar, int Dim, int Mode, int Options>
0880 EIGEN_DEVICE_FUNC inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::prescale(const Scalar& s)
0881 {
0882 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
0883 m_matrix.template topRows<Dim>() *= s;
0884 return *this;
0885 }
0886
0887
0888
0889
0890
0891 template<typename Scalar, int Dim, int Mode, int Options>
0892 template<typename OtherDerived>
0893 EIGEN_DEVICE_FUNC Transform<Scalar,Dim,Mode,Options>&
0894 Transform<Scalar,Dim,Mode,Options>::translate(const MatrixBase<OtherDerived> &other)
0895 {
0896 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
0897 translationExt() += linearExt() * other;
0898 return *this;
0899 }
0900
0901
0902
0903
0904
0905 template<typename Scalar, int Dim, int Mode, int Options>
0906 template<typename OtherDerived>
0907 EIGEN_DEVICE_FUNC Transform<Scalar,Dim,Mode,Options>&
0908 Transform<Scalar,Dim,Mode,Options>::pretranslate(const MatrixBase<OtherDerived> &other)
0909 {
0910 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
0911 if(EIGEN_CONST_CONDITIONAL(int(Mode)==int(Projective)))
0912 affine() += other * m_matrix.row(Dim);
0913 else
0914 translation() += other;
0915 return *this;
0916 }
0917
0918
0919
0920
0921
0922
0923
0924
0925
0926
0927
0928
0929
0930
0931
0932
0933
0934
0935 template<typename Scalar, int Dim, int Mode, int Options>
0936 template<typename RotationType>
0937 EIGEN_DEVICE_FUNC Transform<Scalar,Dim,Mode,Options>&
0938 Transform<Scalar,Dim,Mode,Options>::rotate(const RotationType& rotation)
0939 {
0940 linearExt() *= internal::toRotationMatrix<Scalar,Dim>(rotation);
0941 return *this;
0942 }
0943
0944
0945
0946
0947
0948
0949
0950
0951 template<typename Scalar, int Dim, int Mode, int Options>
0952 template<typename RotationType>
0953 EIGEN_DEVICE_FUNC Transform<Scalar,Dim,Mode,Options>&
0954 Transform<Scalar,Dim,Mode,Options>::prerotate(const RotationType& rotation)
0955 {
0956 m_matrix.template block<Dim,HDim>(0,0) = internal::toRotationMatrix<Scalar,Dim>(rotation)
0957 * m_matrix.template block<Dim,HDim>(0,0);
0958 return *this;
0959 }
0960
0961
0962
0963
0964
0965
0966 template<typename Scalar, int Dim, int Mode, int Options>
0967 EIGEN_DEVICE_FUNC Transform<Scalar,Dim,Mode,Options>&
0968 Transform<Scalar,Dim,Mode,Options>::shear(const Scalar& sx, const Scalar& sy)
0969 {
0970 EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
0971 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
0972 VectorType tmp = linear().col(0)*sy + linear().col(1);
0973 linear() << linear().col(0) + linear().col(1)*sx, tmp;
0974 return *this;
0975 }
0976
0977
0978
0979
0980
0981
0982 template<typename Scalar, int Dim, int Mode, int Options>
0983 EIGEN_DEVICE_FUNC Transform<Scalar,Dim,Mode,Options>&
0984 Transform<Scalar,Dim,Mode,Options>::preshear(const Scalar& sx, const Scalar& sy)
0985 {
0986 EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
0987 EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
0988 m_matrix.template block<Dim,HDim>(0,0) = LinearMatrixType(1, sx, sy, 1) * m_matrix.template block<Dim,HDim>(0,0);
0989 return *this;
0990 }
0991
0992
0993
0994
0995
0996 template<typename Scalar, int Dim, int Mode, int Options>
0997 EIGEN_DEVICE_FUNC inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const TranslationType& t)
0998 {
0999 linear().setIdentity();
1000 translation() = t.vector();
1001 makeAffine();
1002 return *this;
1003 }
1004
1005 template<typename Scalar, int Dim, int Mode, int Options>
1006 EIGEN_DEVICE_FUNC inline Transform<Scalar,Dim,Mode,Options> Transform<Scalar,Dim,Mode,Options>::operator*(const TranslationType& t) const
1007 {
1008 Transform res = *this;
1009 res.translate(t.vector());
1010 return res;
1011 }
1012
1013 template<typename Scalar, int Dim, int Mode, int Options>
1014 EIGEN_DEVICE_FUNC inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const UniformScaling<Scalar>& s)
1015 {
1016 m_matrix.setZero();
1017 linear().diagonal().fill(s.factor());
1018 makeAffine();
1019 return *this;
1020 }
1021
1022 template<typename Scalar, int Dim, int Mode, int Options>
1023 template<typename Derived>
1024 EIGEN_DEVICE_FUNC inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const RotationBase<Derived,Dim>& r)
1025 {
1026 linear() = internal::toRotationMatrix<Scalar,Dim>(r);
1027 translation().setZero();
1028 makeAffine();
1029 return *this;
1030 }
1031
1032 template<typename Scalar, int Dim, int Mode, int Options>
1033 template<typename Derived>
1034 EIGEN_DEVICE_FUNC inline Transform<Scalar,Dim,Mode,Options> Transform<Scalar,Dim,Mode,Options>::operator*(const RotationBase<Derived,Dim>& r) const
1035 {
1036 Transform res = *this;
1037 res.rotate(r.derived());
1038 return res;
1039 }
1040
1041
1042
1043
1044
1045 namespace internal {
1046 template<int Mode> struct transform_rotation_impl {
1047 template<typename TransformType>
1048 EIGEN_DEVICE_FUNC static inline
1049 const typename TransformType::LinearMatrixType run(const TransformType& t)
1050 {
1051 typedef typename TransformType::LinearMatrixType LinearMatrixType;
1052 LinearMatrixType result;
1053 t.computeRotationScaling(&result, (LinearMatrixType*)0);
1054 return result;
1055 }
1056 };
1057 template<> struct transform_rotation_impl<Isometry> {
1058 template<typename TransformType>
1059 EIGEN_DEVICE_FUNC static inline
1060 typename TransformType::ConstLinearPart run(const TransformType& t)
1061 {
1062 return t.linear();
1063 }
1064 };
1065 }
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076 template<typename Scalar, int Dim, int Mode, int Options>
1077 EIGEN_DEVICE_FUNC
1078 typename Transform<Scalar,Dim,Mode,Options>::RotationReturnType
1079 Transform<Scalar,Dim,Mode,Options>::rotation() const
1080 {
1081 return internal::transform_rotation_impl<Mode>::run(*this);
1082 }
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096 template<typename Scalar, int Dim, int Mode, int Options>
1097 template<typename RotationMatrixType, typename ScalingMatrixType>
1098 EIGEN_DEVICE_FUNC void Transform<Scalar,Dim,Mode,Options>::computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const
1099 {
1100
1101 JacobiSVD<LinearMatrixType> svd(linear(), ComputeFullU | ComputeFullV);
1102
1103 Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant() < Scalar(0) ? Scalar(-1) : Scalar(1);
1104 VectorType sv(svd.singularValues());
1105 sv.coeffRef(Dim-1) *= x;
1106 if(scaling) *scaling = svd.matrixV() * sv.asDiagonal() * svd.matrixV().adjoint();
1107 if(rotation)
1108 {
1109 LinearMatrixType m(svd.matrixU());
1110 m.col(Dim-1) *= x;
1111 *rotation = m * svd.matrixV().adjoint();
1112 }
1113 }
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126 template<typename Scalar, int Dim, int Mode, int Options>
1127 template<typename ScalingMatrixType, typename RotationMatrixType>
1128 EIGEN_DEVICE_FUNC void Transform<Scalar,Dim,Mode,Options>::computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const
1129 {
1130
1131 JacobiSVD<LinearMatrixType> svd(linear(), ComputeFullU | ComputeFullV);
1132
1133 Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant() < Scalar(0) ? Scalar(-1) : Scalar(1);
1134 VectorType sv(svd.singularValues());
1135 sv.coeffRef(Dim-1) *= x;
1136 if(scaling) *scaling = svd.matrixU() * sv.asDiagonal() * svd.matrixU().adjoint();
1137 if(rotation)
1138 {
1139 LinearMatrixType m(svd.matrixU());
1140 m.col(Dim-1) *= x;
1141 *rotation = m * svd.matrixV().adjoint();
1142 }
1143 }
1144
1145
1146
1147
1148 template<typename Scalar, int Dim, int Mode, int Options>
1149 template<typename PositionDerived, typename OrientationType, typename ScaleDerived>
1150 EIGEN_DEVICE_FUNC Transform<Scalar,Dim,Mode,Options>&
1151 Transform<Scalar,Dim,Mode,Options>::fromPositionOrientationScale(const MatrixBase<PositionDerived> &position,
1152 const OrientationType& orientation, const MatrixBase<ScaleDerived> &scale)
1153 {
1154 linear() = internal::toRotationMatrix<Scalar,Dim>(orientation);
1155 linear() *= scale.asDiagonal();
1156 translation() = position;
1157 makeAffine();
1158 return *this;
1159 }
1160
1161 namespace internal {
1162
1163 template<int Mode>
1164 struct transform_make_affine
1165 {
1166 template<typename MatrixType>
1167 EIGEN_DEVICE_FUNC static void run(MatrixType &mat)
1168 {
1169 static const int Dim = MatrixType::ColsAtCompileTime-1;
1170 mat.template block<1,Dim>(Dim,0).setZero();
1171 mat.coeffRef(Dim,Dim) = typename MatrixType::Scalar(1);
1172 }
1173 };
1174
1175 template<>
1176 struct transform_make_affine<AffineCompact>
1177 {
1178 template<typename MatrixType> EIGEN_DEVICE_FUNC static void run(MatrixType &) { }
1179 };
1180
1181
1182 template<typename TransformType, int Mode=TransformType::Mode>
1183 struct projective_transform_inverse
1184 {
1185 EIGEN_DEVICE_FUNC static inline void run(const TransformType&, TransformType&)
1186 {}
1187 };
1188
1189 template<typename TransformType>
1190 struct projective_transform_inverse<TransformType, Projective>
1191 {
1192 EIGEN_DEVICE_FUNC static inline void run(const TransformType& m, TransformType& res)
1193 {
1194 res.matrix() = m.matrix().inverse();
1195 }
1196 };
1197
1198 }
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221 template<typename Scalar, int Dim, int Mode, int Options>
1222 EIGEN_DEVICE_FUNC Transform<Scalar,Dim,Mode,Options>
1223 Transform<Scalar,Dim,Mode,Options>::inverse(TransformTraits hint) const
1224 {
1225 Transform res;
1226 if (hint == Projective)
1227 {
1228 internal::projective_transform_inverse<Transform>::run(*this, res);
1229 }
1230 else
1231 {
1232 if (hint == Isometry)
1233 {
1234 res.matrix().template topLeftCorner<Dim,Dim>() = linear().transpose();
1235 }
1236 else if(hint&Affine)
1237 {
1238 res.matrix().template topLeftCorner<Dim,Dim>() = linear().inverse();
1239 }
1240 else
1241 {
1242 eigen_assert(false && "Invalid transform traits in Transform::Inverse");
1243 }
1244
1245 res.matrix().template topRightCorner<Dim,1>()
1246 = - res.matrix().template topLeftCorner<Dim,Dim>() * translation();
1247 res.makeAffine();
1248 }
1249 return res;
1250 }
1251
1252 namespace internal {
1253
1254
1255
1256
1257
1258 template<typename TransformType> struct transform_take_affine_part {
1259 typedef typename TransformType::MatrixType MatrixType;
1260 typedef typename TransformType::AffinePart AffinePart;
1261 typedef typename TransformType::ConstAffinePart ConstAffinePart;
1262 static inline AffinePart run(MatrixType& m)
1263 { return m.template block<TransformType::Dim,TransformType::HDim>(0,0); }
1264 static inline ConstAffinePart run(const MatrixType& m)
1265 { return m.template block<TransformType::Dim,TransformType::HDim>(0,0); }
1266 };
1267
1268 template<typename Scalar, int Dim, int Options>
1269 struct transform_take_affine_part<Transform<Scalar,Dim,AffineCompact, Options> > {
1270 typedef typename Transform<Scalar,Dim,AffineCompact,Options>::MatrixType MatrixType;
1271 static inline MatrixType& run(MatrixType& m) { return m; }
1272 static inline const MatrixType& run(const MatrixType& m) { return m; }
1273 };
1274
1275
1276
1277
1278
1279 template<typename Other, int Mode, int Options, int Dim, int HDim>
1280 struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, Dim,Dim>
1281 {
1282 static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other)
1283 {
1284 transform->linear() = other;
1285 transform->translation().setZero();
1286 transform->makeAffine();
1287 }
1288 };
1289
1290 template<typename Other, int Mode, int Options, int Dim, int HDim>
1291 struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, Dim,HDim>
1292 {
1293 static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other)
1294 {
1295 transform->affine() = other;
1296 transform->makeAffine();
1297 }
1298 };
1299
1300 template<typename Other, int Mode, int Options, int Dim, int HDim>
1301 struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, HDim,HDim>
1302 {
1303 static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other)
1304 { transform->matrix() = other; }
1305 };
1306
1307 template<typename Other, int Options, int Dim, int HDim>
1308 struct transform_construct_from_matrix<Other, AffineCompact,Options,Dim,HDim, HDim,HDim>
1309 {
1310 static inline void run(Transform<typename Other::Scalar,Dim,AffineCompact,Options> *transform, const Other& other)
1311 { transform->matrix() = other.template block<Dim,HDim>(0,0); }
1312 };
1313
1314
1315
1316
1317
1318 template<int LhsMode,int RhsMode>
1319 struct transform_product_result
1320 {
1321 enum
1322 {
1323 Mode =
1324 (LhsMode == (int)Projective || RhsMode == (int)Projective ) ? Projective :
1325 (LhsMode == (int)Affine || RhsMode == (int)Affine ) ? Affine :
1326 (LhsMode == (int)AffineCompact || RhsMode == (int)AffineCompact ) ? AffineCompact :
1327 (LhsMode == (int)Isometry || RhsMode == (int)Isometry ) ? Isometry : Projective
1328 };
1329 };
1330
1331 template< typename TransformType, typename MatrixType, int RhsCols>
1332 struct transform_right_product_impl< TransformType, MatrixType, 0, RhsCols>
1333 {
1334 typedef typename MatrixType::PlainObject ResultType;
1335
1336 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other)
1337 {
1338 return T.matrix() * other;
1339 }
1340 };
1341
1342 template< typename TransformType, typename MatrixType, int RhsCols>
1343 struct transform_right_product_impl< TransformType, MatrixType, 1, RhsCols>
1344 {
1345 enum {
1346 Dim = TransformType::Dim,
1347 HDim = TransformType::HDim,
1348 OtherRows = MatrixType::RowsAtCompileTime,
1349 OtherCols = MatrixType::ColsAtCompileTime
1350 };
1351
1352 typedef typename MatrixType::PlainObject ResultType;
1353
1354 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other)
1355 {
1356 EIGEN_STATIC_ASSERT(OtherRows==HDim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);
1357
1358 typedef Block<ResultType, Dim, OtherCols, int(MatrixType::RowsAtCompileTime)==Dim> TopLeftLhs;
1359
1360 ResultType res(other.rows(),other.cols());
1361 TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() = T.affine() * other;
1362 res.row(OtherRows-1) = other.row(OtherRows-1);
1363
1364 return res;
1365 }
1366 };
1367
1368 template< typename TransformType, typename MatrixType, int RhsCols>
1369 struct transform_right_product_impl< TransformType, MatrixType, 2, RhsCols>
1370 {
1371 enum {
1372 Dim = TransformType::Dim,
1373 HDim = TransformType::HDim,
1374 OtherRows = MatrixType::RowsAtCompileTime,
1375 OtherCols = MatrixType::ColsAtCompileTime
1376 };
1377
1378 typedef typename MatrixType::PlainObject ResultType;
1379
1380 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other)
1381 {
1382 EIGEN_STATIC_ASSERT(OtherRows==Dim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);
1383
1384 typedef Block<ResultType, Dim, OtherCols, true> TopLeftLhs;
1385 ResultType res(Replicate<typename TransformType::ConstTranslationPart, 1, OtherCols>(T.translation(),1,other.cols()));
1386 TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() += T.linear() * other;
1387
1388 return res;
1389 }
1390 };
1391
1392 template< typename TransformType, typename MatrixType >
1393 struct transform_right_product_impl< TransformType, MatrixType, 2, 1>
1394 {
1395 typedef typename TransformType::MatrixType TransformMatrix;
1396 enum {
1397 Dim = TransformType::Dim,
1398 HDim = TransformType::HDim,
1399 OtherRows = MatrixType::RowsAtCompileTime,
1400 WorkingRows = EIGEN_PLAIN_ENUM_MIN(TransformMatrix::RowsAtCompileTime,HDim)
1401 };
1402
1403 typedef typename MatrixType::PlainObject ResultType;
1404
1405 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other)
1406 {
1407 EIGEN_STATIC_ASSERT(OtherRows==Dim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);
1408
1409 Matrix<typename ResultType::Scalar, Dim+1, 1> rhs;
1410 rhs.template head<Dim>() = other; rhs[Dim] = typename ResultType::Scalar(1);
1411 Matrix<typename ResultType::Scalar, WorkingRows, 1> res(T.matrix() * rhs);
1412 return res.template head<Dim>();
1413 }
1414 };
1415
1416
1417
1418
1419
1420
1421 template<typename Other,int Mode, int Options, int Dim, int HDim>
1422 struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, HDim,HDim>
1423 {
1424 typedef Transform<typename Other::Scalar,Dim,Mode,Options> TransformType;
1425 typedef typename TransformType::MatrixType MatrixType;
1426 typedef Transform<typename Other::Scalar,Dim,Projective,Options> ResultType;
1427 static ResultType run(const Other& other,const TransformType& tr)
1428 { return ResultType(other * tr.matrix()); }
1429 };
1430
1431
1432 template<typename Other, int Options, int Dim, int HDim>
1433 struct transform_left_product_impl<Other,AffineCompact,Options,Dim,HDim, HDim,HDim>
1434 {
1435 typedef Transform<typename Other::Scalar,Dim,AffineCompact,Options> TransformType;
1436 typedef typename TransformType::MatrixType MatrixType;
1437 typedef Transform<typename Other::Scalar,Dim,Projective,Options> ResultType;
1438 static ResultType run(const Other& other,const TransformType& tr)
1439 {
1440 ResultType res;
1441 res.matrix().noalias() = other.template block<HDim,Dim>(0,0) * tr.matrix();
1442 res.matrix().col(Dim) += other.col(Dim);
1443 return res;
1444 }
1445 };
1446
1447
1448 template<typename Other,int Mode, int Options, int Dim, int HDim>
1449 struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, Dim,HDim>
1450 {
1451 typedef Transform<typename Other::Scalar,Dim,Mode,Options> TransformType;
1452 typedef typename TransformType::MatrixType MatrixType;
1453 typedef TransformType ResultType;
1454 static ResultType run(const Other& other,const TransformType& tr)
1455 {
1456 ResultType res;
1457 res.affine().noalias() = other * tr.matrix();
1458 res.matrix().row(Dim) = tr.matrix().row(Dim);
1459 return res;
1460 }
1461 };
1462
1463
1464 template<typename Other, int Options, int Dim, int HDim>
1465 struct transform_left_product_impl<Other,AffineCompact,Options,Dim,HDim, Dim,HDim>
1466 {
1467 typedef Transform<typename Other::Scalar,Dim,AffineCompact,Options> TransformType;
1468 typedef typename TransformType::MatrixType MatrixType;
1469 typedef TransformType ResultType;
1470 static ResultType run(const Other& other,const TransformType& tr)
1471 {
1472 ResultType res;
1473 res.matrix().noalias() = other.template block<Dim,Dim>(0,0) * tr.matrix();
1474 res.translation() += other.col(Dim);
1475 return res;
1476 }
1477 };
1478
1479
1480 template<typename Other,int Mode, int Options, int Dim, int HDim>
1481 struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, Dim,Dim>
1482 {
1483 typedef Transform<typename Other::Scalar,Dim,Mode,Options> TransformType;
1484 typedef typename TransformType::MatrixType MatrixType;
1485 typedef TransformType ResultType;
1486 static ResultType run(const Other& other, const TransformType& tr)
1487 {
1488 TransformType res;
1489 if(Mode!=int(AffineCompact))
1490 res.matrix().row(Dim) = tr.matrix().row(Dim);
1491 res.matrix().template topRows<Dim>().noalias()
1492 = other * tr.matrix().template topRows<Dim>();
1493 return res;
1494 }
1495 };
1496
1497
1498
1499
1500
1501 template<typename Scalar, int Dim, int LhsMode, int LhsOptions, int RhsMode, int RhsOptions>
1502 struct transform_transform_product_impl<Transform<Scalar,Dim,LhsMode,LhsOptions>,Transform<Scalar,Dim,RhsMode,RhsOptions>,false >
1503 {
1504 enum { ResultMode = transform_product_result<LhsMode,RhsMode>::Mode };
1505 typedef Transform<Scalar,Dim,LhsMode,LhsOptions> Lhs;
1506 typedef Transform<Scalar,Dim,RhsMode,RhsOptions> Rhs;
1507 typedef Transform<Scalar,Dim,ResultMode,LhsOptions> ResultType;
1508 static ResultType run(const Lhs& lhs, const Rhs& rhs)
1509 {
1510 ResultType res;
1511 res.linear() = lhs.linear() * rhs.linear();
1512 res.translation() = lhs.linear() * rhs.translation() + lhs.translation();
1513 res.makeAffine();
1514 return res;
1515 }
1516 };
1517
1518 template<typename Scalar, int Dim, int LhsMode, int LhsOptions, int RhsMode, int RhsOptions>
1519 struct transform_transform_product_impl<Transform<Scalar,Dim,LhsMode,LhsOptions>,Transform<Scalar,Dim,RhsMode,RhsOptions>,true >
1520 {
1521 typedef Transform<Scalar,Dim,LhsMode,LhsOptions> Lhs;
1522 typedef Transform<Scalar,Dim,RhsMode,RhsOptions> Rhs;
1523 typedef Transform<Scalar,Dim,Projective> ResultType;
1524 static ResultType run(const Lhs& lhs, const Rhs& rhs)
1525 {
1526 return ResultType( lhs.matrix() * rhs.matrix() );
1527 }
1528 };
1529
1530 template<typename Scalar, int Dim, int LhsOptions, int RhsOptions>
1531 struct transform_transform_product_impl<Transform<Scalar,Dim,AffineCompact,LhsOptions>,Transform<Scalar,Dim,Projective,RhsOptions>,true >
1532 {
1533 typedef Transform<Scalar,Dim,AffineCompact,LhsOptions> Lhs;
1534 typedef Transform<Scalar,Dim,Projective,RhsOptions> Rhs;
1535 typedef Transform<Scalar,Dim,Projective> ResultType;
1536 static ResultType run(const Lhs& lhs, const Rhs& rhs)
1537 {
1538 ResultType res;
1539 res.matrix().template topRows<Dim>() = lhs.matrix() * rhs.matrix();
1540 res.matrix().row(Dim) = rhs.matrix().row(Dim);
1541 return res;
1542 }
1543 };
1544
1545 template<typename Scalar, int Dim, int LhsOptions, int RhsOptions>
1546 struct transform_transform_product_impl<Transform<Scalar,Dim,Projective,LhsOptions>,Transform<Scalar,Dim,AffineCompact,RhsOptions>,true >
1547 {
1548 typedef Transform<Scalar,Dim,Projective,LhsOptions> Lhs;
1549 typedef Transform<Scalar,Dim,AffineCompact,RhsOptions> Rhs;
1550 typedef Transform<Scalar,Dim,Projective> ResultType;
1551 static ResultType run(const Lhs& lhs, const Rhs& rhs)
1552 {
1553 ResultType res(lhs.matrix().template leftCols<Dim>() * rhs.matrix());
1554 res.matrix().col(Dim) += lhs.matrix().col(Dim);
1555 return res;
1556 }
1557 };
1558
1559 }
1560
1561 }
1562
1563 #endif