Geometry/Transform.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
5 // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
6 // Copyright (C) 2010 Hauke Heibel <hauke.heibel@gmail.com>
7 //
8 // This Source Code Form is subject to the terms of the Mozilla
9 // Public License v. 2.0. If a copy of the MPL was not distributed
10 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 
12 #ifndef EIGEN_TRANSFORM_H
13 #define EIGEN_TRANSFORM_H
14 
15 namespace Eigen {
16 
17 namespace internal {
18 
19 template<typename Transform>
21 {
22  enum
23  {
24  Dim = Transform::Dim,
25  HDim = Transform::HDim,
26  Mode = Transform::Mode,
27  IsProjective = (int(Mode)==int(Projective))
28  };
29 };
30 
31 template< typename TransformType,
32  typename MatrixType,
34  : int(MatrixType::RowsAtCompileTime) == int(transform_traits<TransformType>::HDim) ? 1
35  : 2>
37 
38 template< typename Other,
39  int Mode,
40  int Options,
41  int Dim,
42  int HDim,
43  int OtherRows=Other::RowsAtCompileTime,
44  int OtherCols=Other::ColsAtCompileTime>
46 
47 template< typename Lhs,
48  typename Rhs,
49  bool AnyProjective =
53 
54 template< typename Other,
55  int Mode,
56  int Options,
57  int Dim,
58  int HDim,
59  int OtherRows=Other::RowsAtCompileTime,
60  int OtherCols=Other::ColsAtCompileTime>
62 
63 template<typename TransformType> struct transform_take_affine_part;
64 
65 } // end namespace internal
66 
175 template<typename _Scalar, int _Dim, int _Mode, int _Options>
176 class Transform
177 {
178 public:
180  enum {
181  Mode = _Mode,
182  Options = _Options,
183  Dim = _Dim,
184  HDim = _Dim+1,
185  Rows = int(Mode)==(AffineCompact) ? Dim : HDim
186  };
188  typedef _Scalar Scalar;
189  typedef DenseIndex Index;
193  typedef const MatrixType ConstMatrixType;
201  typedef typename internal::conditional<int(Mode)==int(AffineCompact),
202  MatrixType&,
205  typedef typename internal::conditional<int(Mode)==int(AffineCompact),
206  const MatrixType&,
216 
217  // this intermediate enum is needed to avoid an ICE with gcc 3.4 and 4.0
218  enum { TransformTimeDiagonalMode = ((Mode==int(Isometry))?Affine:int(Mode)) };
221 
222 protected:
223 
224  MatrixType m_matrix;
225 
226 public:
227 
230  inline Transform()
231  {
232  check_template_params();
233  if (int(Mode)==Affine)
234  makeAffine();
235  }
236 
237  inline Transform(const Transform& other)
238  {
239  check_template_params();
240  m_matrix = other.m_matrix;
241  }
242 
243  inline explicit Transform(const TranslationType& t)
244  {
245  check_template_params();
246  *this = t;
247  }
248  inline explicit Transform(const UniformScaling<Scalar>& s)
249  {
250  check_template_params();
251  *this = s;
252  }
253  template<typename Derived>
254  inline explicit Transform(const RotationBase<Derived, Dim>& r)
255  {
256  check_template_params();
257  *this = r;
258  }
259 
260  inline Transform& operator=(const Transform& other)
261  { m_matrix = other.m_matrix; return *this; }
262 
264 
266  template<typename OtherDerived>
267  inline explicit Transform(const EigenBase<OtherDerived>& other)
268  {
270  YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY);
271 
272  check_template_params();
274  }
275 
277  template<typename OtherDerived>
279  {
281  YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY);
282 
284  return *this;
285  }
286 
287  template<int OtherOptions>
289  {
290  check_template_params();
291  // only the options change, we can directly copy the matrices
292  m_matrix = other.matrix();
293  }
294 
295  template<int OtherMode,int OtherOptions>
297  {
298  check_template_params();
299  // prevent conversions as:
300  // Affine | AffineCompact | Isometry = Projective
302  YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION)
303 
304  // prevent conversions as:
305  // Isometry = Affine | AffineCompact
306  EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(OtherMode==int(Affine)||OtherMode==int(AffineCompact), Mode!=int(Isometry)),
307  YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION)
308 
309  enum { ModeIsAffineCompact = Mode == int(AffineCompact),
310  OtherModeIsAffineCompact = OtherMode == int(AffineCompact)
311  };
312 
313  if(ModeIsAffineCompact == OtherModeIsAffineCompact)
314  {
315  // We need the block expression because the code is compiled for all
316  // combinations of transformations and will trigger a compile time error
317  // if one tries to assign the matrices directly
318  m_matrix.template block<Dim,Dim+1>(0,0) = other.matrix().template block<Dim,Dim+1>(0,0);
319  makeAffine();
320  }
321  else if(OtherModeIsAffineCompact)
322  {
323  typedef typename Transform<Scalar,Dim,OtherMode,OtherOptions>::MatrixType OtherMatrixType;
325  }
326  else
327  {
328  // here we know that Mode == AffineCompact and OtherMode != AffineCompact.
329  // if OtherMode were Projective, the static assert above would already have caught it.
330  // So the only possibility is that OtherMode == Affine
331  linear() = other.linear();
332  translation() = other.translation();
333  }
334  }
335 
336  template<typename OtherDerived>
338  {
339  check_template_params();
340  other.evalTo(*this);
341  }
342 
343  template<typename OtherDerived>
345  {
346  other.evalTo(*this);
347  return *this;
348  }
349 
350  #ifdef EIGEN_QT_SUPPORT
351  inline Transform(const QMatrix& other);
352  inline Transform& operator=(const QMatrix& other);
353  inline QMatrix toQMatrix(void) const;
354  inline Transform(const QTransform& other);
355  inline Transform& operator=(const QTransform& other);
356  inline QTransform toQTransform(void) const;
357  #endif
358 
361  inline Scalar operator() (Index row, Index col) const { return m_matrix(row,col); }
364  inline Scalar& operator() (Index row, Index col) { return m_matrix(row,col); }
365 
367  inline const MatrixType& matrix() const { return m_matrix; }
369  inline MatrixType& matrix() { return m_matrix; }
370 
372  inline ConstLinearPart linear() const { return ConstLinearPart(m_matrix,0,0); }
374  inline LinearPart linear() { return LinearPart(m_matrix,0,0); }
375 
377  inline ConstAffinePart affine() const { return take_affine_part::run(m_matrix); }
379  inline AffinePart affine() { return take_affine_part::run(m_matrix); }
380 
382  inline ConstTranslationPart translation() const { return ConstTranslationPart(m_matrix,0,Dim); }
384  inline TranslationPart translation() { return TranslationPart(m_matrix,0,Dim); }
385 
397  // note: this function is defined here because some compilers cannot find the respective declaration
398  template<typename OtherDerived>
402 
410  template<typename OtherDerived> friend
414 
421  template<typename DiagonalDerived>
422  inline const TransformTimeDiagonalReturnType
424  {
425  TransformTimeDiagonalReturnType res(*this);
426  res.linear() *= b;
427  return res;
428  }
429 
436  template<typename DiagonalDerived>
437  friend inline TransformTimeDiagonalReturnType
439  {
440  TransformTimeDiagonalReturnType res;
441  res.linear().noalias() = a*b.linear();
442  res.translation().noalias() = a*b.translation();
443  if (Mode!=int(AffineCompact))
444  res.matrix().row(Dim) = b.matrix().row(Dim);
445  return res;
446  }
447 
448  template<typename OtherDerived>
449  inline Transform& operator*=(const EigenBase<OtherDerived>& other) { return *this = *this * other; }
450 
452  inline const Transform operator * (const Transform& other) const
453  {
455  }
456 
457  #ifdef __INTEL_COMPILER
458 private:
459  // this intermediate structure permits to workaround a bug in ICC 11:
460  // error: template instantiation resulted in unexpected function type of "Eigen::Transform<double, 3, 32, 0>
461  // (const Eigen::Transform<double, 3, 2, 0> &) const"
462  // (the meaning of a name may have changed since the template declaration -- the type of the template is:
463  // "Eigen::internal::transform_transform_product_impl<Eigen::Transform<double, 3, 32, 0>,
464  // Eigen::Transform<double, 3, Mode, Options>, <expression>>::ResultType (const Eigen::Transform<double, 3, Mode, Options> &) const")
465  //
466  template<int OtherMode,int OtherOptions> struct icc_11_workaround
467  {
469  typedef typename ProductType::ResultType ResultType;
470  };
471 
472 public:
474  template<int OtherMode,int OtherOptions>
475  inline typename icc_11_workaround<OtherMode,OtherOptions>::ResultType
477  {
478  typedef typename icc_11_workaround<OtherMode,OtherOptions>::ProductType ProductType;
479  return ProductType::run(*this,other);
480  }
481  #else
482 
483  template<int OtherMode,int OtherOptions>
486  {
488  }
489  #endif
490 
492  void setIdentity() { m_matrix.setIdentity(); }
493 
498  static const Transform Identity()
499  {
500  return Transform(MatrixType::Identity());
501  }
502 
503  template<typename OtherDerived>
504  inline Transform& scale(const MatrixBase<OtherDerived> &other);
505 
506  template<typename OtherDerived>
507  inline Transform& prescale(const MatrixBase<OtherDerived> &other);
508 
509  inline Transform& scale(const Scalar& s);
510  inline Transform& prescale(const Scalar& s);
511 
512  template<typename OtherDerived>
513  inline Transform& translate(const MatrixBase<OtherDerived> &other);
514 
515  template<typename OtherDerived>
516  inline Transform& pretranslate(const MatrixBase<OtherDerived> &other);
517 
518  template<typename RotationType>
519  inline Transform& rotate(const RotationType& rotation);
520 
521  template<typename RotationType>
522  inline Transform& prerotate(const RotationType& rotation);
523 
524  Transform& shear(const Scalar& sx, const Scalar& sy);
525  Transform& preshear(const Scalar& sx, const Scalar& sy);
526 
527  inline Transform& operator=(const TranslationType& t);
528  inline Transform& operator*=(const TranslationType& t) { return translate(t.vector()); }
529  inline Transform operator*(const TranslationType& t) const;
530 
531  inline Transform& operator=(const UniformScaling<Scalar>& t);
532  inline Transform& operator*=(const UniformScaling<Scalar>& s) { return scale(s.factor()); }
534  {
536  res.scale(s.factor());
537  return res;
538  }
539 
540  inline Transform& operator*=(const DiagonalMatrix<Scalar,Dim>& s) { linear() *= s; return *this; }
541 
542  template<typename Derived>
543  inline Transform& operator=(const RotationBase<Derived,Dim>& r);
544  template<typename Derived>
545  inline Transform& operator*=(const RotationBase<Derived,Dim>& r) { return rotate(r.toRotationMatrix()); }
546  template<typename Derived>
547  inline Transform operator*(const RotationBase<Derived,Dim>& r) const;
548 
549  const LinearMatrixType rotation() const;
550  template<typename RotationMatrixType, typename ScalingMatrixType>
551  void computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const;
552  template<typename ScalingMatrixType, typename RotationMatrixType>
553  void computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const;
554 
555  template<typename PositionDerived, typename OrientationType, typename ScaleDerived>
556  Transform& fromPositionOrientationScale(const MatrixBase<PositionDerived> &position,
557  const OrientationType& orientation, const MatrixBase<ScaleDerived> &scale);
558 
559  inline Transform inverse(TransformTraits traits = (TransformTraits)Mode) const;
560 
562  const Scalar* data() const { return m_matrix.data(); }
564  Scalar* data() { return m_matrix.data(); }
565 
571  template<typename NewScalarType>
574 
576  template<typename OtherScalarType>
578  {
579  check_template_params();
580  m_matrix = other.matrix().template cast<Scalar>();
581  }
582 
587  bool isApprox(const Transform& other, const typename NumTraits<Scalar>::Real& prec = NumTraits<Scalar>::dummy_precision()) const
588  { return m_matrix.isApprox(other.m_matrix, prec); }
589 
592  void makeAffine()
593  {
594  if(int(Mode)!=int(AffineCompact))
595  {
596  matrix().template block<1,Dim>(Dim,0).setZero();
597  matrix().coeffRef(Dim,Dim) = Scalar(1);
598  }
599  }
600 
606  { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,Dim>(0,0); }
612  { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,Dim>(0,0); }
613 
619  { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,1>(0,Dim); }
625  { return m_matrix.template block<int(Mode)==int(Projective)?HDim:Dim,1>(0,Dim); }
626 
627 
628  #ifdef EIGEN_TRANSFORM_PLUGIN
629  #include EIGEN_TRANSFORM_PLUGIN
630  #endif
631 
632 protected:
633  #ifndef EIGEN_PARSED_BY_DOXYGEN
635  {
636  EIGEN_STATIC_ASSERT((Options & (DontAlign|RowMajor)) == Options, INVALID_MATRIX_TEMPLATE_PARAMETERS)
637  }
638  #endif
639 
640 };
641 
650 
659 
668 
677 
678 /**************************
679 *** Optional QT support ***
680 **************************/
681 
682 #ifdef EIGEN_QT_SUPPORT
683 
687 template<typename Scalar, int Dim, int Mode,int Options>
689 {
690  check_template_params();
691  *this = other;
692 }
693 
698 template<typename Scalar, int Dim, int Mode,int Options>
700 {
701  EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
702  m_matrix << other.m11(), other.m21(), other.dx(),
703  other.m12(), other.m22(), other.dy(),
704  0, 0, 1;
705  return *this;
706 }
707 
714 template<typename Scalar, int Dim, int Mode, int Options>
716 {
717  check_template_params();
718  EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
719  return QMatrix(m_matrix.coeff(0,0), m_matrix.coeff(1,0),
720  m_matrix.coeff(0,1), m_matrix.coeff(1,1),
721  m_matrix.coeff(0,2), m_matrix.coeff(1,2));
722 }
723 
728 template<typename Scalar, int Dim, int Mode,int Options>
729 Transform<Scalar,Dim,Mode,Options>::Transform(const QTransform& other)
730 {
731  check_template_params();
732  *this = other;
733 }
734 
739 template<typename Scalar, int Dim, int Mode, int Options>
741 {
742  check_template_params();
743  EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
744  if (Mode == int(AffineCompact))
745  m_matrix << other.m11(), other.m21(), other.dx(),
746  other.m12(), other.m22(), other.dy();
747  else
748  m_matrix << other.m11(), other.m21(), other.dx(),
749  other.m12(), other.m22(), other.dy(),
750  other.m13(), other.m23(), other.m33();
751  return *this;
752 }
753 
758 template<typename Scalar, int Dim, int Mode, int Options>
760 {
761  EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
762  if (Mode == int(AffineCompact))
763  return QTransform(m_matrix.coeff(0,0), m_matrix.coeff(1,0),
764  m_matrix.coeff(0,1), m_matrix.coeff(1,1),
765  m_matrix.coeff(0,2), m_matrix.coeff(1,2));
766  else
767  return QTransform(m_matrix.coeff(0,0), m_matrix.coeff(1,0), m_matrix.coeff(2,0),
768  m_matrix.coeff(0,1), m_matrix.coeff(1,1), m_matrix.coeff(2,1),
769  m_matrix.coeff(0,2), m_matrix.coeff(1,2), m_matrix.coeff(2,2));
770 }
771 #endif
772 
773 /*********************
774 *** Procedural API ***
775 *********************/
776 
781 template<typename Scalar, int Dim, int Mode, int Options>
782 template<typename OtherDerived>
785 {
787  EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
788  linearExt().noalias() = (linearExt() * other.asDiagonal());
789  return *this;
790 }
791 
796 template<typename Scalar, int Dim, int Mode, int Options>
798 {
799  EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
800  linearExt() *= s;
801  return *this;
802 }
803 
808 template<typename Scalar, int Dim, int Mode, int Options>
809 template<typename OtherDerived>
812 {
814  EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
815  m_matrix.template block<Dim,HDim>(0,0).noalias() = (other.asDiagonal() * m_matrix.template block<Dim,HDim>(0,0));
816  return *this;
817 }
818 
823 template<typename Scalar, int Dim, int Mode, int Options>
825 {
826  EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
827  m_matrix.template topRows<Dim>() *= s;
828  return *this;
829 }
830 
835 template<typename Scalar, int Dim, int Mode, int Options>
836 template<typename OtherDerived>
839 {
841  translationExt() += linearExt() * other;
842  return *this;
843 }
844 
849 template<typename Scalar, int Dim, int Mode, int Options>
850 template<typename OtherDerived>
853 {
855  if(int(Mode)==int(Projective))
856  affine() += other * m_matrix.row(Dim);
857  else
858  translation() += other;
859  return *this;
860 }
861 
879 template<typename Scalar, int Dim, int Mode, int Options>
880 template<typename RotationType>
882 Transform<Scalar,Dim,Mode,Options>::rotate(const RotationType& rotation)
883 {
884  linearExt() *= internal::toRotationMatrix<Scalar,Dim>(rotation);
885  return *this;
886 }
887 
895 template<typename Scalar, int Dim, int Mode, int Options>
896 template<typename RotationType>
899 {
900  m_matrix.template block<Dim,HDim>(0,0) = internal::toRotationMatrix<Scalar,Dim>(rotation)
901  * m_matrix.template block<Dim,HDim>(0,0);
902  return *this;
903 }
904 
910 template<typename Scalar, int Dim, int Mode, int Options>
912 Transform<Scalar,Dim,Mode,Options>::shear(const Scalar& sx, const Scalar& sy)
913 {
914  EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
915  EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
916  VectorType tmp = linear().col(0)*sy + linear().col(1);
917  linear() << linear().col(0) + linear().col(1)*sx, tmp;
918  return *this;
919 }
920 
926 template<typename Scalar, int Dim, int Mode, int Options>
928 Transform<Scalar,Dim,Mode,Options>::preshear(const Scalar& sx, const Scalar& sy)
929 {
930  EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
931  EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
932  m_matrix.template block<Dim,HDim>(0,0) = LinearMatrixType(1, sx, sy, 1) * m_matrix.template block<Dim,HDim>(0,0);
933  return *this;
934 }
935 
936 /******************************************************
937 *** Scaling, Translation and Rotation compatibility ***
938 ******************************************************/
939 
940 template<typename Scalar, int Dim, int Mode, int Options>
942 {
943  linear().setIdentity();
944  translation() = t.vector();
945  makeAffine();
946  return *this;
947 }
948 
949 template<typename Scalar, int Dim, int Mode, int Options>
951 {
952  Transform res = *this;
953  res.translate(t.vector());
954  return res;
955 }
956 
957 template<typename Scalar, int Dim, int Mode, int Options>
959 {
960  m_matrix.setZero();
961  linear().diagonal().fill(s.factor());
962  makeAffine();
963  return *this;
964 }
965 
966 template<typename Scalar, int Dim, int Mode, int Options>
967 template<typename Derived>
969 {
970  linear() = internal::toRotationMatrix<Scalar,Dim>(r);
971  translation().setZero();
972  makeAffine();
973  return *this;
974 }
975 
976 template<typename Scalar, int Dim, int Mode, int Options>
977 template<typename Derived>
979 {
980  Transform res = *this;
981  res.rotate(r.derived());
982  return res;
983 }
984 
985 /************************
986 *** Special functions ***
987 ************************/
988 
996 template<typename Scalar, int Dim, int Mode, int Options>
999 {
1000  LinearMatrixType result;
1001  computeRotationScaling(&result, (LinearMatrixType*)0);
1002  return result;
1003 }
1004 
1005 
1017 template<typename Scalar, int Dim, int Mode, int Options>
1018 template<typename RotationMatrixType, typename ScalingMatrixType>
1019 void Transform<Scalar,Dim,Mode,Options>::computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const
1020 {
1022 
1023  Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant(); // so x has absolute value 1
1024  VectorType sv(svd.singularValues());
1025  sv.coeffRef(0) *= x;
1026  if(scaling) scaling->lazyAssign(svd.matrixV() * sv.asDiagonal() * svd.matrixV().adjoint());
1027  if(rotation)
1028  {
1029  LinearMatrixType m(svd.matrixU());
1030  m.col(0) /= x;
1031  rotation->lazyAssign(m * svd.matrixV().adjoint());
1032  }
1033 }
1034 
1046 template<typename Scalar, int Dim, int Mode, int Options>
1047 template<typename ScalingMatrixType, typename RotationMatrixType>
1048 void Transform<Scalar,Dim,Mode,Options>::computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const
1049 {
1051 
1052  Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant(); // so x has absolute value 1
1053  VectorType sv(svd.singularValues());
1054  sv.coeffRef(0) *= x;
1055  if(scaling) scaling->lazyAssign(svd.matrixU() * sv.asDiagonal() * svd.matrixU().adjoint());
1056  if(rotation)
1057  {
1058  LinearMatrixType m(svd.matrixU());
1059  m.col(0) /= x;
1060  rotation->lazyAssign(m * svd.matrixV().adjoint());
1061  }
1062 }
1063 
1067 template<typename Scalar, int Dim, int Mode, int Options>
1068 template<typename PositionDerived, typename OrientationType, typename ScaleDerived>
1071  const OrientationType& orientation, const MatrixBase<ScaleDerived> &scale)
1072 {
1073  linear() = internal::toRotationMatrix<Scalar,Dim>(orientation);
1074  linear() *= scale.asDiagonal();
1075  translation() = position;
1076  makeAffine();
1077  return *this;
1078 }
1079 
1080 namespace internal {
1081 
1082 // selector needed to avoid taking the inverse of a 3x4 matrix
1083 template<typename TransformType, int Mode=TransformType::Mode>
1085 {
1086  static inline void run(const TransformType&, TransformType&)
1087  {}
1088 };
1089 
1090 template<typename TransformType>
1092 {
1093  static inline void run(const TransformType& m, TransformType& res)
1094  {
1095  res.matrix() = m.matrix().inverse();
1096  }
1097 };
1098 
1099 } // end namespace internal
1100 
1101 
1122 template<typename Scalar, int Dim, int Mode, int Options>
1125 {
1126  Transform res;
1127  if (hint == Projective)
1128  {
1130  }
1131  else
1132  {
1133  if (hint == Isometry)
1134  {
1135  res.matrix().template topLeftCorner<Dim,Dim>() = linear().transpose();
1136  }
1137  else if(hint&Affine)
1138  {
1139  res.matrix().template topLeftCorner<Dim,Dim>() = linear().inverse();
1140  }
1141  else
1142  {
1143  eigen_assert(false && "Invalid transform traits in Transform::Inverse");
1144  }
1145  // translation and remaining parts
1146  res.matrix().template topRightCorner<Dim,1>()
1147  = - res.matrix().template topLeftCorner<Dim,Dim>() * translation();
1148  res.makeAffine(); // we do need this, because in the beginning res is uninitialized
1149  }
1150  return res;
1151 }
1152 
1153 namespace internal {
1154 
1155 /*****************************************************
1156 *** Specializations of take affine part ***
1157 *****************************************************/
1158 
1159 template<typename TransformType> struct transform_take_affine_part {
1160  typedef typename TransformType::MatrixType MatrixType;
1161  typedef typename TransformType::AffinePart AffinePart;
1162  typedef typename TransformType::ConstAffinePart ConstAffinePart;
1163  static inline AffinePart run(MatrixType& m)
1164  { return m.template block<TransformType::Dim,TransformType::HDim>(0,0); }
1165  static inline ConstAffinePart run(const MatrixType& m)
1166  { return m.template block<TransformType::Dim,TransformType::HDim>(0,0); }
1167 };
1168 
1169 template<typename Scalar, int Dim, int Options>
1172  static inline MatrixType& run(MatrixType& m) { return m; }
1173  static inline const MatrixType& run(const MatrixType& m) { return m; }
1174 };
1175 
1176 /*****************************************************
1177 *** Specializations of construct from matrix ***
1178 *****************************************************/
1179 
1180 template<typename Other, int Mode, int Options, int Dim, int HDim>
1181 struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, Dim,Dim>
1182 {
1183  static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other)
1184  {
1185  transform->linear() = other;
1186  transform->translation().setZero();
1187  transform->makeAffine();
1188  }
1189 };
1190 
1191 template<typename Other, int Mode, int Options, int Dim, int HDim>
1192 struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, Dim,HDim>
1193 {
1194  static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other)
1195  {
1196  transform->affine() = other;
1197  transform->makeAffine();
1198  }
1199 };
1200 
1201 template<typename Other, int Mode, int Options, int Dim, int HDim>
1202 struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, HDim,HDim>
1203 {
1204  static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other)
1205  { transform->matrix() = other; }
1206 };
1207 
1208 template<typename Other, int Options, int Dim, int HDim>
1210 {
1211  static inline void run(Transform<typename Other::Scalar,Dim,AffineCompact,Options> *transform, const Other& other)
1212  { transform->matrix() = other.template block<Dim,HDim>(0,0); }
1213 };
1214 
1215 /**********************************************************
1216 *** Specializations of operator* with rhs EigenBase ***
1217 **********************************************************/
1218 
1219 template<int LhsMode,int RhsMode>
1221 {
1222  enum
1223  {
1224  Mode =
1225  (LhsMode == (int)Projective || RhsMode == (int)Projective ) ? Projective :
1226  (LhsMode == (int)Affine || RhsMode == (int)Affine ) ? Affine :
1227  (LhsMode == (int)AffineCompact || RhsMode == (int)AffineCompact ) ? AffineCompact :
1228  (LhsMode == (int)Isometry || RhsMode == (int)Isometry ) ? Isometry : Projective
1229  };
1230 };
1231 
1232 template< typename TransformType, typename MatrixType >
1233 struct transform_right_product_impl< TransformType, MatrixType, 0 >
1234 {
1235  typedef typename MatrixType::PlainObject ResultType;
1236 
1237  static EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other)
1238  {
1239  return T.matrix() * other;
1240  }
1241 };
1242 
1243 template< typename TransformType, typename MatrixType >
1244 struct transform_right_product_impl< TransformType, MatrixType, 1 >
1245 {
1246  enum {
1247  Dim = TransformType::Dim,
1248  HDim = TransformType::HDim,
1249  OtherRows = MatrixType::RowsAtCompileTime,
1250  OtherCols = MatrixType::ColsAtCompileTime
1251  };
1252 
1253  typedef typename MatrixType::PlainObject ResultType;
1254 
1255  static EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other)
1256  {
1257  EIGEN_STATIC_ASSERT(OtherRows==HDim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);
1258 
1260 
1261  ResultType res(other.rows(),other.cols());
1262  TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() = T.affine() * other;
1263  res.row(OtherRows-1) = other.row(OtherRows-1);
1264 
1265  return res;
1266  }
1267 };
1268 
1269 template< typename TransformType, typename MatrixType >
1270 struct transform_right_product_impl< TransformType, MatrixType, 2 >
1271 {
1272  enum {
1273  Dim = TransformType::Dim,
1274  HDim = TransformType::HDim,
1275  OtherRows = MatrixType::RowsAtCompileTime,
1276  OtherCols = MatrixType::ColsAtCompileTime
1277  };
1278 
1279  typedef typename MatrixType::PlainObject ResultType;
1280 
1281  static EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other)
1282  {
1283  EIGEN_STATIC_ASSERT(OtherRows==Dim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);
1284 
1285  typedef Block<ResultType, Dim, OtherCols, true> TopLeftLhs;
1286  ResultType res(Replicate<typename TransformType::ConstTranslationPart, 1, OtherCols>(T.translation(),1,other.cols()));
1287  TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() += T.linear() * other;
1288 
1289  return res;
1290  }
1291 };
1292 
1293 /**********************************************************
1294 *** Specializations of operator* with lhs EigenBase ***
1295 **********************************************************/
1296 
1297 // generic HDim x HDim matrix * T => Projective
1298 template<typename Other,int Mode, int Options, int Dim, int HDim>
1299 struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, HDim,HDim>
1300 {
1304  static ResultType run(const Other& other,const TransformType& tr)
1305  { return ResultType(other * tr.matrix()); }
1306 };
1307 
1308 // generic HDim x HDim matrix * AffineCompact => Projective
1309 template<typename Other, int Options, int Dim, int HDim>
1311 {
1315  static ResultType run(const Other& other,const TransformType& tr)
1316  {
1317  ResultType res;
1318  res.matrix().noalias() = other.template block<HDim,Dim>(0,0) * tr.matrix();
1319  res.matrix().col(Dim) += other.col(Dim);
1320  return res;
1321  }
1322 };
1323 
1324 // affine matrix * T
1325 template<typename Other,int Mode, int Options, int Dim, int HDim>
1326 struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, Dim,HDim>
1327 {
1330  typedef TransformType ResultType;
1331  static ResultType run(const Other& other,const TransformType& tr)
1332  {
1333  ResultType res;
1334  res.affine().noalias() = other * tr.matrix();
1335  res.matrix().row(Dim) = tr.matrix().row(Dim);
1336  return res;
1337  }
1338 };
1339 
1340 // affine matrix * AffineCompact
1341 template<typename Other, int Options, int Dim, int HDim>
1343 {
1346  typedef TransformType ResultType;
1347  static ResultType run(const Other& other,const TransformType& tr)
1348  {
1349  ResultType res;
1350  res.matrix().noalias() = other.template block<Dim,Dim>(0,0) * tr.matrix();
1351  res.translation() += other.col(Dim);
1352  return res;
1353  }
1354 };
1355 
1356 // linear matrix * T
1357 template<typename Other,int Mode, int Options, int Dim, int HDim>
1358 struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, Dim,Dim>
1359 {
1362  typedef TransformType ResultType;
1363  static ResultType run(const Other& other, const TransformType& tr)
1364  {
1365  TransformType res;
1366  if(Mode!=int(AffineCompact))
1367  res.matrix().row(Dim) = tr.matrix().row(Dim);
1368  res.matrix().template topRows<Dim>().noalias()
1369  = other * tr.matrix().template topRows<Dim>();
1370  return res;
1371  }
1372 };
1373 
1374 /**********************************************************
1375 *** Specializations of operator* with another Transform ***
1376 **********************************************************/
1377 
1378 template<typename Scalar, int Dim, int LhsMode, int LhsOptions, int RhsMode, int RhsOptions>
1379 struct transform_transform_product_impl<Transform<Scalar,Dim,LhsMode,LhsOptions>,Transform<Scalar,Dim,RhsMode,RhsOptions>,false >
1380 {
1385  static ResultType run(const Lhs& lhs, const Rhs& rhs)
1386  {
1387  ResultType res;
1388  res.linear() = lhs.linear() * rhs.linear();
1389  res.translation() = lhs.linear() * rhs.translation() + lhs.translation();
1390  res.makeAffine();
1391  return res;
1392  }
1393 };
1394 
1395 template<typename Scalar, int Dim, int LhsMode, int LhsOptions, int RhsMode, int RhsOptions>
1396 struct transform_transform_product_impl<Transform<Scalar,Dim,LhsMode,LhsOptions>,Transform<Scalar,Dim,RhsMode,RhsOptions>,true >
1397 {
1401  static ResultType run(const Lhs& lhs, const Rhs& rhs)
1402  {
1403  return ResultType( lhs.matrix() * rhs.matrix() );
1404  }
1405 };
1406 
1407 template<typename Scalar, int Dim, int LhsOptions, int RhsOptions>
1408 struct transform_transform_product_impl<Transform<Scalar,Dim,AffineCompact,LhsOptions>,Transform<Scalar,Dim,Projective,RhsOptions>,true >
1409 {
1413  static ResultType run(const Lhs& lhs, const Rhs& rhs)
1414  {
1415  ResultType res;
1416  res.matrix().template topRows<Dim>() = lhs.matrix() * rhs.matrix();
1417  res.matrix().row(Dim) = rhs.matrix().row(Dim);
1418  return res;
1419  }
1420 };
1421 
1422 template<typename Scalar, int Dim, int LhsOptions, int RhsOptions>
1423 struct transform_transform_product_impl<Transform<Scalar,Dim,Projective,LhsOptions>,Transform<Scalar,Dim,AffineCompact,RhsOptions>,true >
1424 {
1428  static ResultType run(const Lhs& lhs, const Rhs& rhs)
1429  {
1430  ResultType res(lhs.matrix().template leftCols<Dim>() * rhs.matrix());
1431  res.matrix().col(Dim) += lhs.matrix().col(Dim);
1432  return res;
1433  }
1434 };
1435 
1436 } // end namespace internal
1437 
1438 } // end namespace Eigen
1439 
1440 #endif // EIGEN_TRANSFORM_H
Matrix< Scalar, Dim, Dim, Options > LinearMatrixType
static void run(const TransformType &m, TransformType &res)
EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar, _Dim==Dynamic?Dynamic:(_Dim+1)*(_Dim+1)) enum
TranslationPart translation()
Transform & operator*=(const RotationBase< Derived, Dim > &r)
static void run(const TransformType &, TransformType &)
Transform & operator=(const EigenBase< OtherDerived > &other)
Transform(const TranslationType &t)
#define EIGEN_STRONG_INLINE
Transform< float, 3, Affine > Affine3f
void computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const
Transform< double, 2, AffineCompact > AffineCompact2d
Transform(const RotationBase< Derived, Dim > &r)
#define Transform
Definition: All.h:37
Translation< Scalar, Dim > TranslationType
const VectorType & vector() const
static void run(Transform< typename Other::Scalar, Dim, Mode, Options > *transform, const Other &other)
const MatrixType ConstMatrixType
Transform & operator*=(const TranslationType &t)
Transform< Scalar, Dim, TransformTimeDiagonalMode > TransformTimeDiagonalReturnType
XmlRpcServer s
Represents a diagonal matrix with its storage.
Transform & operator*=(const EigenBase< OtherDerived > &other)
Transform & operator=(const Transform &other)
const Block< ConstMatrixType, Dim, Dim, int(Mode)==(AffineCompact)> ConstLinearPart
const Scalar & factor() const
Definition: LDLT.h:16
Holds information about the various numeric (i.e. scalar) types allowed by Eigen. ...
Definition: NumTraits.h:88
const internal::permut_matrix_product_retval< PermutationDerived, Derived, OnTheRight > operator*(const MatrixBase< Derived > &matrix, const PermutationBase< PermutationDerived > &permutation)
#define EIGEN_STATIC_ASSERT(CONDITION, MSG)
Definition: StaticAssert.h:111
const SingularValuesType & singularValues() const
Definition: JacobiSVD.h:630
Derived & derived()
Definition: EigenBase.h:34
const Block< MatrixType, int(Mode)==int(Projective)?HDim:Dim, 1 > translationExt() const
Transform(const Transform< Scalar, Dim, Mode, OtherOptions > &other)
MatrixType & matrix()
ConstAffinePart affine() const
Transform & prerotate(const RotationType &rotation)
static void run(Transform< typename Other::Scalar, Dim, Mode, Options > *transform, const Other &other)
Transform & shear(Scalar sx, Scalar sy)
void setZero()
Represents a translation transformation.
Transform< double, 2, Projective > Projective2d
const CwiseUnaryOp< internal::scalar_inverse_op< Scalar >, const Derived > inverse() const
Transform< float, 2, AffineCompact > AffineCompact2f
Transform & pretranslate(const MatrixBase< OtherDerived > &other)
Transform & preshear(Scalar sx, Scalar sy)
Transform & operator=(const ReturnByValue< OtherDerived > &other)
EIGEN_STRONG_INLINE const Scalar & coeff(Index rowId, Index colId) const
TransformTraits
Definition: Constants.h:389
Transform< double, 3, Affine > Affine3d
internal::cast_return_type< Transform, Transform< NewScalarType, Dim, Mode, Options > >::type cast() const
Transform< Scalar, Dim,(int(Mode)==int(Isometry)?Affine:Isometry)> operator*(const UniformScaling< Scalar > &s) const
Matrix< Scalar, Dim, 1 > VectorType
static EIGEN_STRONG_INLINE ResultType run(const TransformType &T, const MatrixType &other)
Expression of the multiple replication of a matrix or vector.
Definition: Replicate.h:62
Common base class for compact rotation representations.
Transform(const UniformScaling< Scalar > &s)
Transform(const ReturnByValue< OtherDerived > &other)
internal::conditional< int(Mode)==int(AffineCompact), const MatrixType &, const Block< const MatrixType, Dim, HDim > >::type ConstAffinePart
Transform< double, 3, Isometry > Isometry3d
static const Transform Identity()
Returns an identity transformation.
Transform & operator*=(const UniformScaling< Scalar > &s)
const Scalar * data() const
Transform(const Transform< Scalar, Dim, OtherMode, OtherOptions > &other)
TFSIMD_FORCE_INLINE const tfScalar & x() const
void computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const
internal::conditional< int(Mode)==int(AffineCompact), MatrixType &, Block< MatrixType, Dim, HDim > >::type AffinePart
Transform & translate(const MatrixBase< OtherDerived > &other)
Transform< float, 2, Projective > Projective2f
Derived & setZero(Index size)
ConstTranslationPart translation() const
const Block< MatrixType, int(Mode)==int(Projective)?HDim:Dim, Dim > linearExt() const
static EIGEN_STRONG_INLINE ResultType run(const TransformType &T, const MatrixType &other)
Transform & prescale(const MatrixBase< OtherDerived > &other)
Block< MatrixType, Dim, 1, int(Mode)==(AffineCompact)> TranslationPart
Transform< float, 3, Projective > Projective3f
static void run(Transform< typename Other::Scalar, Dim, Mode, Options > *transform, const Other &other)
EIGEN_DEFAULT_DENSE_INDEX_TYPE DenseIndex
Definition: XprHelper.h:27
EIGEN_STRONG_INLINE const Scalar * data() const
Transform & rotate(const RotationType &rotation)
Block< MatrixType, int(Mode)==int(Projective)?HDim:Dim, 1 > translationExt()
const ei_transform_product_impl< OtherDerived, _Dim, _Dim+1 >::ResultType operator*(const MatrixBase< OtherDerived > &other) const
bool isApprox(const Transform &other, const typename NumTraits< Scalar >::Real &prec=NumTraits< Scalar >::dummy_precision()) const
Transform< float, 3, AffineCompact > AffineCompact3f
Transform< double, 3, AffineCompact > AffineCompact3d
Transform< float, 2, Affine > Affine2f
static EIGEN_STRONG_INLINE void check_template_params()
TransformType::ConstAffinePart ConstAffinePart
Transform< float, 3, Isometry > Isometry3f
const MatrixType & matrix() const
Expression of a fixed-size or dynamic-size block.
Definition: Core/Block.h:102
RowXpr row(Index i)
Definition: BlockMethods.h:725
Transform< double, 2, Affine > Affine2d
static void run(Transform< typename Other::Scalar, Dim, AffineCompact, Options > *transform, const Other &other)
Transform & scale(const MatrixBase< OtherDerived > &other)
Transform< double, 2, Isometry > Isometry2d
TFSIMD_FORCE_INLINE Vector3 rotate(const Vector3 &wAxis, const tfScalar angle) const
Transform & operator*=(const DiagonalMatrix< Scalar, Dim > &s)
Two-sided Jacobi SVD decomposition of a rectangular matrix.
const Block< ConstMatrixType, Dim, 1, int(Mode)==(AffineCompact)> ConstTranslationPart
Transform(const Transform &other)
ConstLinearPart linear() const
const MatrixUType & matrixU() const
Definition: JacobiSVD.h:602
#define EIGEN_IMPLIES(a, b)
LinearMatrixType rotation() const
const MatrixType inverse(TransformTraits traits=Affine) const
static ConstAffinePart run(const MatrixType &m)
internal::make_proper_matrix_type< Scalar, Rows, HDim, Options >::type MatrixType
const int Dynamic
Definition: Constants.h:21
Transform & fromPositionOrientationScale(const MatrixBase< PositionDerived > &position, const OrientationType &orientation, const MatrixBase< ScaleDerived > &scale)
ColXpr col(Index i)
Definition: BlockMethods.h:708
internal::transform_take_affine_part< Transform > take_affine_part
Transform(const Transform< OtherScalarType, Dim, Mode, Options > &other)
const DiagonalWrapper< const Derived > asDiagonal() const
The matrix class, also used for vectors and row-vectors.
Definition: Matrix.h:127
#define eigen_assert(x)
void evalTo(Dest &dst) const
Definition: ReturnByValue.h:60
Transform(const EigenBase< OtherDerived > &other)
Block< MatrixType, Dim, Dim, int(Mode)==(AffineCompact)> LinearPart
Base class for all dense matrices, vectors, and expressions.
Definition: MatrixBase.h:48
Block< MatrixType, int(Mode)==int(Projective)?HDim:Dim, Dim > linearExt()
Represents an homogeneous transformation in a N dimensional space.
const MatrixVType & matrixV() const
Definition: JacobiSVD.h:618
RotationMatrixType toRotationMatrix() const
Transform< float, 2, Isometry > Isometry2f
Transform< double, 3, Projective > Projective3d
#define EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(TYPE, SIZE)
Definition: StaticAssert.h:141
static EIGEN_STRONG_INLINE ResultType run(const TransformType &T, const MatrixType &other)


tuw_aruco
Author(s): Lukas Pfeifhofer
autogenerated on Mon Jun 10 2019 15:41:01