13#ifndef EIGEN_TRANSFORM_H
14#define EIGEN_TRANSFORM_H
17#include "./InternalHeaderCheck.h"
23template <
typename Transform>
24struct transform_traits {
27 HDim = Transform::HDim,
28 Mode = Transform::Mode,
33template <
typename TransformType,
typename MatrixType,
34 int Case = transform_traits<TransformType>::IsProjective ? 0
35 : int(MatrixType::RowsAtCompileTime) == int(transform_traits<TransformType>::HDim) ? 1
37 int RhsCols = MatrixType::ColsAtCompileTime>
38struct transform_right_product_impl;
40template <
typename Other,
int Mode,
int Options,
int Dim,
int HDim,
int OtherRows = Other::RowsAtCompileTime,
41 int OtherCols = Other::ColsAtCompileTime>
42struct transform_left_product_impl;
44template <
typename Lhs,
typename Rhs,
45 bool AnyProjective = transform_traits<Lhs>::IsProjective || transform_traits<Rhs>::IsProjective>
46struct transform_transform_product_impl;
48template <
typename Other,
int Mode,
int Options,
int Dim,
int HDim,
int OtherRows = Other::RowsAtCompileTime,
49 int OtherCols = Other::ColsAtCompileTime>
50struct transform_construct_from_matrix;
52template <
typename TransformType>
53struct transform_take_affine_part;
55template <
typename LhsScalar,
typename RhsScalar,
typename BinaryOp,
typename TargetScalar,
typename =
void>
56struct has_matching_binary_op_traits : std::false_type {};
58template <
typename LhsScalar,
typename RhsScalar,
typename BinaryOp,
typename TargetScalar>
59struct has_matching_binary_op_traits<LhsScalar, RhsScalar, BinaryOp, TargetScalar,
60 void_t<typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, BinaryOp>::ReturnType>>
61 : std::integral_constant<
62 bool, std::is_convertible<typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, BinaryOp>::ReturnType,
63 TargetScalar>::value ||
64 std::is_assignable<TargetScalar&,
65 typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, BinaryOp>::ReturnType>::value> {};
67template <
typename TargetScalar,
typename Derived,
typename LhsScalar,
typename RhsScalar,
typename BinaryOp,
69struct transform_convert_arg {
70 EIGEN_DEVICE_FUNC
static auto run(
const MatrixBase<Derived>& mat) {
return mat.template cast<TargetScalar>(); }
73template <
typename TargetScalar,
typename Derived,
typename LhsScalar,
typename RhsScalar,
typename BinaryOp>
74struct transform_convert_arg<
75 TargetScalar, Derived, LhsScalar, RhsScalar, BinaryOp,
76 std::enable_if_t<std::is_same<typename Derived::Scalar, TargetScalar>::value ||
77 has_matching_binary_op_traits<LhsScalar, RhsScalar, BinaryOp, TargetScalar>::value>> {
78 EIGEN_DEVICE_FUNC
static const Derived& run(
const MatrixBase<Derived>& mat) {
return mat.derived(); }
81template <
typename Scalar_,
int Dim_,
int Mode_,
int Options_>
82struct traits<Transform<Scalar_, Dim_, Mode_, Options_> > {
83 using Scalar = Scalar_;
84 using StorageIndex = Eigen::Index;
85 using StorageKind = Dense;
87 Dim1 = Dim_ == Dynamic ? Dim_ : Dim_ + 1,
88 RowsAtCompileTime = Mode_ ==
Projective ? Dim1 : Dim_,
89 ColsAtCompileTime = Dim1,
90 MaxRowsAtCompileTime = RowsAtCompileTime,
91 MaxColsAtCompileTime = ColsAtCompileTime,
97struct transform_make_affine;
221template <
typename Scalar_,
int Dim_,
int Mode_,
int Options_>
225 Dim_ == Dynamic ? Dynamic : (Dim_ + 1) * (Dim_ + 1))
235 using StorageIndex = Eigen::Index;
238 using MatrixType =
typename internal::make_proper_matrix_type<Scalar, Rows, HDim, Options>::type;
273 check_template_params();
284 check_template_params();
287 EIGEN_DEVICE_FUNC
inline explicit Transform(
const UniformScaling<Scalar>& s) {
288 check_template_params();
291 template <
typename Derived>
292 EIGEN_DEVICE_FUNC
inline explicit Transform(
const RotationBase<Derived, Dim>& r) {
293 check_template_params();
297 using take_affine_part = internal::transform_take_affine_part<Transform>;
300 template <
typename OtherDerived>
303 (std::is_same<Scalar, typename OtherDerived::Scalar>::value),
304 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY);
306 check_template_params();
307 internal::transform_construct_from_matrix<OtherDerived, Mode, Options, Dim, HDim>::run(
this, other.
derived());
311 template <
typename OtherDerived>
314 (std::is_same<Scalar, typename OtherDerived::Scalar>::value),
315 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY);
317 internal::transform_construct_from_matrix<OtherDerived, Mode, Options, Dim, HDim>::run(
this, other.
derived());
321 template <
int OtherOptions>
323 check_template_params();
325 m_matrix = other.
matrix();
328 template <
int OtherMode,
int OtherOptions>
330 check_template_params();
333 EIGEN_STATIC_ASSERT(internal::check_implication(OtherMode ==
int(
Projective), Mode ==
int(
Projective)),
334 YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION)
340 YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION)
347 if (EIGEN_CONST_CONDITIONAL(ModeIsAffineCompact == OtherModeIsAffineCompact)) {
351 m_matrix.template block<Dim, Dim + 1>(0, 0) = other.matrix().template block<Dim, Dim + 1>(0, 0);
353 }
else if (EIGEN_CONST_CONDITIONAL(OtherModeIsAffineCompact)) {
355 internal::transform_construct_from_matrix<OtherMatrixType, Mode, Options, Dim, HDim>::run(
this, other.matrix());
360 linear() = other.linear();
365 template <
typename OtherDerived>
366 EIGEN_DEVICE_FUNC
Transform(
const ReturnByValue<OtherDerived>& other) {
367 check_template_params();
371 template <
typename OtherDerived>
377#ifdef EIGEN_QT_SUPPORT
378#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
381 inline QMatrix toQMatrix(
void)
const;
388 EIGEN_DEVICE_FUNC
constexpr Index rows() const noexcept {
389 return int(Mode) == int(
Projective) ? m_matrix.cols() : (m_matrix.cols() - 1);
391 EIGEN_DEVICE_FUNC
constexpr Index cols() const noexcept {
return m_matrix.cols(); }
400#ifdef EIGEN_MULTIDIMENSIONAL_SUBSCRIPT
403 EIGEN_DEVICE_FUNC
inline Scalar operator[](Index row, Index col)
const {
return m_matrix[row, col]; }
406 EIGEN_DEVICE_FUNC
inline Scalar& operator[](Index row, Index col) {
return m_matrix[row, col]; }
455 template <
typename OtherDerived>
456 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const typename internal::transform_right_product_impl<
Transform,
457 OtherDerived>::ResultType
459 return internal::transform_right_product_impl<Transform, OtherDerived>::run(*
this, other.derived());
469 template <
typename OtherDerived>
470 friend EIGEN_DEVICE_FUNC
inline const typename internal::transform_left_product_impl<OtherDerived, Mode, Options,
471 Dim_, Dim_ + 1>::ResultType
473 return internal::transform_left_product_impl<OtherDerived, Mode, Options, Dim, HDim>::run(a.derived(), b);
482 template <
typename DiagonalDerived>
486 res.linearExt() *= b;
496 template <
typename DiagonalDerived>
506 template <
typename OtherDerived>
508 return *
this = *
this * other;
513 return internal::transform_transform_product_impl<Transform, Transform>::run(*
this, other);
517 template <
int OtherMode,
int OtherOptions>
518 EIGEN_DEVICE_FUNC
inline
519 typename internal::transform_transform_product_impl<
Transform,
522 return internal::transform_transform_product_impl<Transform, Transform<Scalar, Dim, OtherMode, OtherOptions> >::run(
535 template <
typename OtherDerived>
538 template <
typename OtherDerived>
544 template <
typename OtherDerived>
547 template <
typename OtherDerived>
550 template <
typename RotationType>
553 template <
typename RotationType>
571 res.scale(s.factor());
575 EIGEN_DEVICE_FUNC
inline Transform& operator*=(
const DiagonalMatrix<Scalar, Dim>& s) {
580 template <
typename Derived>
582 template <
typename Derived>
583 EIGEN_DEVICE_FUNC
inline Transform& operator*=(
const RotationBase<Derived, Dim>& r) {
584 return rotate(r.toRotationMatrix());
586 template <
typename Derived>
587 EIGEN_DEVICE_FUNC
inline Transform operator*(
const RotationBase<Derived, Dim>& r)
const;
590 EIGEN_DEVICE_FUNC RotationReturnType
rotation()
const;
592 template <
typename RotationMatrixType,
typename ScalingMatrixType>
594 template <
typename ScalingMatrixType,
typename RotationMatrixType>
597 template <
typename PositionDerived,
typename OrientationType,
typename ScaleDerived>
599 const OrientationType& orientation,
605 EIGEN_DEVICE_FUNC
constexpr const Scalar*
data()
const {
return m_matrix.data(); }
607 EIGEN_DEVICE_FUNC
constexpr Scalar*
data() {
return m_matrix.data(); }
614 template <
typename NewScalarType>
615 EIGEN_DEVICE_FUNC
inline
616 typename internal::cast_return_type<Transform, Transform<NewScalarType, Dim, Mode, Options> >::type
618 return typename internal::cast_return_type<Transform, Transform<NewScalarType, Dim, Mode, Options> >::type(*
this);
622 template <
typename OtherScalarType>
624 check_template_params();
632 EIGEN_DEVICE_FUNC
bool isApprox(
const Transform& other,
const typename NumTraits<Scalar>::Real& prec =
633 NumTraits<Scalar>::dummy_precision())
const {
634 return m_matrix.isApprox(other.m_matrix, prec);
639 EIGEN_DEVICE_FUNC
void makeAffine() { internal::transform_make_affine<int(Mode)>::run(m_matrix); }
646 return m_matrix.template block < int(Mode) == int(Projective) ? HDim : Dim, Dim > (0, 0);
652 EIGEN_DEVICE_FUNC
inline const Block<
MatrixType, int(Mode) == int(
Projective) ? HDim : Dim, Dim> linearExt()
const {
653 return m_matrix.template block < int(Mode) == int(Projective) ? HDim : Dim, Dim > (0, 0);
660 EIGEN_DEVICE_FUNC
inline Block<
MatrixType, int(Mode) == int(
Projective) ? HDim : Dim, 1> translationExt() {
661 return m_matrix.template block < int(Mode) == int(Projective) ? HDim : Dim, 1 > (0, Dim);
667 EIGEN_DEVICE_FUNC
inline const Block<
MatrixType, int(Mode) == int(
Projective) ? HDim : Dim, 1> translationExt()
669 return m_matrix.template block < int(Mode) == int(Projective) ? HDim : Dim, 1 > (0, Dim);
672#ifdef EIGEN_TRANSFORM_PLUGIN
673#include EIGEN_TRANSFORM_PLUGIN
677#ifndef EIGEN_PARSED_BY_DOXYGEN
678 EIGEN_DEVICE_FUNC
static EIGEN_STRONG_INLINE
void check_template_params() {
679 EIGEN_STATIC_ASSERT((Options & (
DontAlign |
RowMajor)) == Options, INVALID_MATRIX_TEMPLATE_PARAMETERS)
724#ifdef EIGEN_QT_SUPPORT
726#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
731template <
typename Scalar,
int Dim,
int Mode,
int Options>
733 check_template_params();
741template <
typename Scalar,
int Dim,
int Mode,
int Options>
743 EIGEN_STATIC_ASSERT(Dim == 2, YOU_MADE_A_PROGRAMMING_MISTAKE)
745 m_matrix << other.m11(), other.m21(), other.dx(), other.m12(), other.m22(), other.dy();
747 m_matrix << other.m11(), other.m21(), other.dx(), other.m12(), other.m22(), other.dy(), 0, 0, 1;
757template <
typename Scalar,
int Dim,
int Mode,
int Options>
759 check_template_params();
760 EIGEN_STATIC_ASSERT(Dim == 2, YOU_MADE_A_PROGRAMMING_MISTAKE)
761 return QMatrix(m_matrix.coeff(0, 0), m_matrix.coeff(1, 0), m_matrix.coeff(0, 1), m_matrix.coeff(1, 1),
762 m_matrix.coeff(0, 2), m_matrix.coeff(1, 2));
770template <
typename Scalar,
int Dim,
int Mode,
int Options>
772 check_template_params();
780template <
typename Scalar,
int Dim,
int Mode,
int Options>
782 check_template_params();
783 EIGEN_STATIC_ASSERT(Dim == 2, YOU_MADE_A_PROGRAMMING_MISTAKE)
785 m_matrix << other.m11(), other.m21(), other.dx(), other.m12(), other.m22(), other.dy();
787 m_matrix << other.m11(), other.m21(), other.dx(), other.m12(), other.m22(), other.dy(), other.m13(), other.m23(),
796template <
typename Scalar,
int Dim,
int Mode,
int Options>
798 EIGEN_STATIC_ASSERT(Dim == 2, YOU_MADE_A_PROGRAMMING_MISTAKE)
800 return QTransform(m_matrix.coeff(0, 0), m_matrix.coeff(1, 0), m_matrix.coeff(0, 1), m_matrix.coeff(1, 1),
801 m_matrix.coeff(0, 2), m_matrix.coeff(1, 2));
803 return QTransform(m_matrix.coeff(0, 0), m_matrix.coeff(1, 0), m_matrix.coeff(2, 0), m_matrix.coeff(0, 1),
804 m_matrix.coeff(1, 1), m_matrix.coeff(2, 1), m_matrix.coeff(0, 2), m_matrix.coeff(1, 2),
805 m_matrix.coeff(2, 2));
817template <
typename Scalar,
int Dim,
int Mode,
int Options>
818template <
typename OtherDerived>
821 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,
int(Dim))
822 EIGEN_STATIC_ASSERT(Mode !=
int(
Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
823 linearExt() = linearExt() * other.
asDiagonal();
831template <
typename Scalar,
int Dim,
int Mode,
int Options>
834 EIGEN_STATIC_ASSERT(Mode !=
int(
Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
843template <
typename Scalar,
int Dim,
int Mode,
int Options>
844template <
typename OtherDerived>
847 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,
int(Dim))
848 EIGEN_STATIC_ASSERT(Mode !=
int(
Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
857template <
typename Scalar,
int Dim,
int Mode,
int Options>
860 EIGEN_STATIC_ASSERT(Mode !=
int(
Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
861 m_matrix.template topRows<Dim>() *= s;
869template <
typename Scalar,
int Dim,
int Mode,
int Options>
870template <
typename OtherDerived>
873 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,
int(Dim))
876 internal::transform_convert_arg<
Scalar, OtherDerived,
Scalar,
typename OtherDerived::Scalar,
877 internal::fast_mult_op<Scalar, typename OtherDerived::Scalar>>::run(other);
885template <
typename Scalar,
int Dim,
int Mode,
int Options>
886template <
typename OtherDerived>
889 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,
int(Dim))
890 if (EIGEN_CONST_CONDITIONAL(
int(Mode) ==
int(
Projective)))
892 internal::transform_convert_arg<
Scalar, OtherDerived,
typename OtherDerived::Scalar,
Scalar,
893 internal::fast_mult_op<typename OtherDerived::Scalar, Scalar>>::run(other) *
897 internal::transform_convert_arg<
Scalar, OtherDerived,
Scalar,
typename OtherDerived::Scalar,
898 internal::scalar_sum_op<Scalar, typename OtherDerived::Scalar>>::run(other);
904template <
typename TransformType,
typename RotationType,
typename Enable =
void>
905struct transform_rotate_impl {
906 EIGEN_DEVICE_FUNC
static inline void run(TransformType& t,
const RotationType& rotation) {
907 t.linearExt() *= internal::toRotationMatrix<typename TransformType::Scalar, TransformType::Dim>(rotation);
911template <
typename TransformType,
typename Derived>
912struct transform_rotate_impl<TransformType, Derived,
913 std::enable_if_t<std::is_base_of<MatrixBase<Derived>, Derived>::value>> {
914 EIGEN_DEVICE_FUNC
static inline void run(TransformType& t,
const Derived& rotation) {
915 using Scalar =
typename TransformType::Scalar;
916 t.linearExt() *= internal::transform_convert_arg<
917 Scalar, Derived, Scalar,
typename Derived::Scalar,
918 internal::fast_mult_op<Scalar, typename Derived::Scalar>>::run(rotation);
922template <
typename TransformType,
typename Derived>
923struct transform_rotate_impl<
924 TransformType, Derived,
925 std::enable_if_t<std::is_base_of<RotationBase<Derived, TransformType::Dim>, Derived>::value>> {
926 EIGEN_DEVICE_FUNC
static inline void run(TransformType& t,
const Derived& rotation) {
927 t.rotate(rotation.toRotationMatrix());
931template <
typename TransformType,
typename OtherScalar>
932struct transform_rotate_impl<TransformType, OtherScalar, std::enable_if_t<std::is_scalar<OtherScalar>::value>> {
933 EIGEN_DEVICE_FUNC
static inline void run(TransformType& t,
const OtherScalar& rotation) {
934 EIGEN_STATIC_ASSERT(TransformType::Dim == 2, YOU_MADE_A_PROGRAMMING_MISTAKE)
935 t.rotate(Rotation2D<OtherScalar>(rotation).toRotationMatrix());
939template <
typename TransformType,
typename RotationType,
typename Enable =
void>
940struct transform_prerotate_impl {
941 EIGEN_DEVICE_FUNC
static inline void run(TransformType& t,
const RotationType& rotation) {
942 t.matrix().template block<TransformType::Dim, TransformType::HDim>(0, 0) =
943 internal::toRotationMatrix<typename TransformType::Scalar, TransformType::Dim>(rotation) *
944 t.matrix().template block<TransformType::Dim, TransformType::HDim>(0, 0);
948template <
typename TransformType,
typename Derived>
949struct transform_prerotate_impl<TransformType, Derived,
950 std::enable_if_t<std::is_base_of<MatrixBase<Derived>, Derived>::value>> {
951 EIGEN_DEVICE_FUNC
static inline void run(TransformType& t,
const Derived& rotation) {
952 using Scalar =
typename TransformType::Scalar;
953 t.
matrix().template block<TransformType::Dim, TransformType::HDim>(0, 0) =
954 internal::transform_convert_arg<
955 Scalar, Derived,
typename Derived::Scalar, Scalar,
956 internal::fast_mult_op<typename Derived::Scalar, Scalar>>::run(rotation) *
957 t.
matrix().template block<TransformType::Dim, TransformType::HDim>(0, 0);
961template <
typename TransformType,
typename Derived>
962struct transform_prerotate_impl<
963 TransformType, Derived,
964 std::enable_if_t<std::is_base_of<RotationBase<Derived, TransformType::Dim>, Derived>::value>> {
965 EIGEN_DEVICE_FUNC
static inline void run(TransformType& t,
const Derived& rotation) {
966 t.prerotate(rotation.toRotationMatrix());
970template <
typename TransformType,
typename OtherScalar>
971struct transform_prerotate_impl<TransformType, OtherScalar, std::enable_if_t<std::is_scalar<OtherScalar>::value>> {
972 EIGEN_DEVICE_FUNC
static inline void run(TransformType& t,
const OtherScalar& rotation) {
973 EIGEN_STATIC_ASSERT(TransformType::Dim == 2, YOU_MADE_A_PROGRAMMING_MISTAKE)
974 t.prerotate(Rotation2D<OtherScalar>(rotation).toRotationMatrix());
997template <
typename Scalar,
int Dim,
int Mode,
int Options>
998template <
typename RotationType>
1001 internal::transform_rotate_impl<Transform, RotationType>::run(*
this,
rotation);
1012template <
typename Scalar,
int Dim,
int Mode,
int Options>
1013template <
typename RotationType>
1016 internal::transform_prerotate_impl<Transform, RotationType>::run(*
this,
rotation);
1025template <
typename Scalar,
int Dim,
int Mode,
int Options>
1028 EIGEN_STATIC_ASSERT(
int(Dim) == 2, YOU_MADE_A_PROGRAMMING_MISTAKE)
1029 EIGEN_STATIC_ASSERT(Mode !=
int(
Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
1040template <
typename Scalar,
int Dim,
int Mode,
int Options>
1043 EIGEN_STATIC_ASSERT(
int(Dim) == 2, YOU_MADE_A_PROGRAMMING_MISTAKE)
1044 EIGEN_STATIC_ASSERT(Mode !=
int(
Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
1045 m_matrix.template block<Dim, HDim>(0, 0) =
1046 LinearMatrixType({{1, sy}, {sx, 1}}) * m_matrix.template block<Dim, HDim>(0, 0);
1054template <
typename Scalar,
int Dim,
int Mode,
int Options>
1056 const TranslationType& t) {
1058 translation() = t.vector();
1063template <
typename Scalar,
int Dim,
int Mode,
int Options>
1065 const TranslationType& t)
const {
1066 Transform res = *
this;
1067 res.translate(t.vector());
1071template <
typename Scalar,
int Dim,
int Mode,
int Options>
1075 linear().diagonal().fill(s.factor());
1080template <
typename Scalar,
int Dim,
int Mode,
int Options>
1081template <
typename Derived>
1084 linear() = internal::toRotationMatrix<Scalar, Dim>(r);
1085 translation().setZero();
1090template <
typename Scalar,
int Dim,
int Mode,
int Options>
1091template <
typename Derived>
1095 res.rotate(r.derived());
1105struct transform_rotation_impl {
1106 template <
typename TransformType>
1107 EIGEN_DEVICE_FUNC
static inline const typename TransformType::LinearMatrixType run(
const TransformType& t) {
1108 using LinearMatrixType =
typename TransformType::LinearMatrixType;
1109 LinearMatrixType result;
1110 t.computeRotationScaling(&result, (LinearMatrixType*)0);
1115struct transform_rotation_impl<
Isometry> {
1116 template <
typename TransformType>
1117 EIGEN_DEVICE_FUNC
static inline typename TransformType::ConstLinearPart run(
const TransformType& t) {
1132template <
typename Scalar,
int Dim,
int Mode,
int Options>
1133EIGEN_DEVICE_FUNC
typename Transform<Scalar, Dim, Mode, Options>::RotationReturnType
1135 return internal::transform_rotation_impl<Mode>::run(*
this);
1149template <
typename Scalar,
int Dim,
int Mode,
int Options>
1150template <
typename RotationMatrixType,
typename ScalingMatrixType>
1152 ScalingMatrixType* scaling)
const {
1161 if (scaling) (*scaling).noalias() = svd.
matrixV() * sv.asDiagonal() * svd.
matrixV().adjoint();
1164 m.col(Dim - 1) *= x;
1165 (*rotation).noalias() = m * svd.
matrixV().adjoint();
1180template <
typename Scalar,
int Dim,
int Mode,
int Options>
1181template <
typename ScalingMatrixType,
typename RotationMatrixType>
1183 ScalingMatrixType* scaling, RotationMatrixType*
rotation)
const {
1192 if (scaling) *scaling = svd.
matrixU() * sv.asDiagonal() * svd.
matrixU().adjoint();
1195 m.col(Dim - 1) *= x;
1203template <
typename Scalar,
int Dim,
int Mode,
int Options>
1204template <
typename PositionDerived,
typename OrientationType,
typename ScaleDerived>
1207 const OrientationType& orientation,
1209 linear() = internal::toRotationMatrix<Scalar, Dim>(orientation);
1210 linear() *= scale.asDiagonal();
1219struct transform_make_affine {
1220 template <
typename MatrixType>
1221 EIGEN_DEVICE_FUNC
static void run(MatrixType& mat) {
1222 static const int Dim = MatrixType::ColsAtCompileTime - 1;
1223 mat.template block<1, Dim>(Dim, 0).setZero();
1224 mat.coeffRef(Dim, Dim) =
typename MatrixType::Scalar(1);
1230 template <
typename MatrixType>
1231 EIGEN_DEVICE_FUNC
static void run(MatrixType&) {}
1237template <
typename TransformType,
int Mode = TransformType::Mode>
1238struct projective_transform_inverse {
1239 EIGEN_DEVICE_FUNC
static inline void run(
const TransformType& m, TransformType& res) { res = m.inverse(
Affine); }
1242template <
typename TransformType>
1243struct projective_transform_inverse<TransformType,
Projective> {
1244 EIGEN_DEVICE_FUNC
static inline void run(
const TransformType& m, TransformType& res) {
1245 res.matrix() = m.matrix().inverse();
1271template <
typename Scalar,
int Dim,
int Mode,
int Options>
1276 internal::projective_transform_inverse<Transform>::run(*
this, res);
1279 res.
matrix().template topLeftCorner<Dim, Dim>() =
linear().transpose();
1280 }
else if (hint &
Affine) {
1281 res.
matrix().template topLeftCorner<Dim, Dim>() =
linear().inverse();
1283 eigen_assert(
false &&
"Invalid transform traits in Transform::Inverse");
1286 res.
matrix().template topRightCorner<Dim, 1>().noalias() =
1299template <
typename TransformType>
1300struct transform_take_affine_part {
1301 using MatrixType =
typename TransformType::MatrixType;
1302 using AffinePart =
typename TransformType::AffinePart;
1303 using ConstAffinePart =
typename TransformType::ConstAffinePart;
1304 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE AffinePart run(MatrixType& m) {
1305 return m.template block<TransformType::Dim, TransformType::HDim>(0, 0);
1307 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ConstAffinePart run(
const MatrixType& m) {
1308 return m.template block<TransformType::Dim, TransformType::HDim>(0, 0);
1312template <
typename Scalar,
int Dim,
int Options>
1313struct transform_take_affine_part<Transform<Scalar, Dim,
AffineCompact, Options> > {
1315 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE MatrixType& run(MatrixType& m) {
return m; }
1316 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const MatrixType& run(
const MatrixType& m) {
return m; }
1323template <
typename Other,
int Mode,
int Options,
int Dim,
int HDim>
1324struct transform_construct_from_matrix<Other, Mode, Options, Dim, HDim, Dim, Dim> {
1325 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void run(
1326 Transform<typename Other::Scalar, Dim, Mode, Options>* transform,
const Other& other) {
1327 transform->linear() = other;
1328 transform->translation().setZero();
1329 transform->makeAffine();
1333template <
typename Other,
int Mode,
int Options,
int Dim,
int HDim>
1334struct transform_construct_from_matrix<Other, Mode, Options, Dim, HDim, Dim, HDim> {
1335 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void run(
1336 Transform<typename Other::Scalar, Dim, Mode, Options>* transform,
const Other& other) {
1337 transform->affine() = other;
1338 transform->makeAffine();
1342template <
typename Other,
int Mode,
int Options,
int Dim,
int HDim>
1343struct transform_construct_from_matrix<Other, Mode, Options, Dim, HDim, HDim, HDim> {
1344 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void run(
1345 Transform<typename Other::Scalar, Dim, Mode, Options>* transform,
const Other& other) {
1346 transform->matrix() = other;
1350template <
typename Other,
int Options,
int Dim,
int HDim>
1351struct transform_construct_from_matrix<Other,
AffineCompact, Options, Dim, HDim, HDim, HDim> {
1352 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void run(
1353 Transform<typename Other::Scalar, Dim, AffineCompact, Options>* transform,
const Other& other) {
1354 transform->matrix() = other.template block<Dim, HDim>(0, 0);
1362template <
int LhsMode,
int RhsMode>
1363struct transform_product_result {
1373template <
typename TransformType,
typename MatrixType,
int RhsCols>
1374struct transform_right_product_impl<TransformType, MatrixType, 0, RhsCols> {
1375 using ResultType =
typename MatrixType::PlainObject;
1377 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ResultType run(
const TransformType& T,
const MatrixType& other) {
1378 return T.matrix() * other;
1382template <
typename TransformType,
typename MatrixType,
int RhsCols>
1383struct transform_right_product_impl<TransformType, MatrixType, 1, RhsCols> {
1385 Dim = TransformType::Dim,
1386 HDim = TransformType::HDim,
1387 OtherRows = MatrixType::RowsAtCompileTime,
1388 OtherCols = MatrixType::ColsAtCompileTime
1391 using ResultType =
typename MatrixType::PlainObject;
1393 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ResultType run(
const TransformType& T,
const MatrixType& other) {
1394 EIGEN_STATIC_ASSERT(OtherRows == HDim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);
1396 using TopLeftLhs = Block<ResultType, Dim, OtherCols, int(MatrixType::RowsAtCompileTime) == Dim>;
1398 ResultType res(other.rows(), other.cols());
1399 TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() = T.affine() * other;
1400 res.row(OtherRows - 1) = other.row(OtherRows - 1);
1406template <
typename TransformType,
typename MatrixType,
int RhsCols>
1407struct transform_right_product_impl<TransformType, MatrixType, 2, RhsCols> {
1409 Dim = TransformType::Dim,
1410 HDim = TransformType::HDim,
1411 OtherRows = MatrixType::RowsAtCompileTime,
1412 OtherCols = MatrixType::ColsAtCompileTime
1415 using ResultType =
typename MatrixType::PlainObject;
1417 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ResultType run(
const TransformType& T,
const MatrixType& other) {
1418 EIGEN_STATIC_ASSERT(OtherRows == Dim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);
1420 using TopLeftLhs = Block<ResultType, Dim, OtherCols, true>;
1422 Replicate<typename TransformType::ConstTranslationPart, 1, OtherCols>(T.translation(), 1, other.cols()));
1423 TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() += T.linear() * other;
1429template <
typename TransformType,
typename MatrixType>
1430struct transform_right_product_impl<TransformType, MatrixType, 2, 1>
1432 using TransformMatrix =
typename TransformType::MatrixType;
1434 Dim = TransformType::Dim,
1435 HDim = TransformType::HDim,
1436 OtherRows = MatrixType::RowsAtCompileTime,
1437 WorkingRows = plain_enum_min(TransformMatrix::RowsAtCompileTime, HDim)
1440 using ResultType =
typename MatrixType::PlainObject;
1442 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ResultType run(
const TransformType& T,
const MatrixType& other) {
1443 EIGEN_STATIC_ASSERT(OtherRows == Dim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);
1445 Matrix<typename ResultType::Scalar, Dim + 1, 1> rhs;
1446 rhs.template head<Dim>() = other;
1447 rhs[Dim] =
typename ResultType::Scalar(1);
1448 Matrix<typename ResultType::Scalar, WorkingRows, 1> res(T.matrix() * rhs);
1449 return res.template head<Dim>();
1458template <
typename Other,
int Mode,
int Options,
int Dim,
int HDim>
1459struct transform_left_product_impl<Other, Mode, Options, Dim, HDim, HDim, HDim> {
1460 using TransformType = Transform<typename Other::Scalar, Dim, Mode, Options>;
1461 using MatrixType =
typename TransformType::MatrixType;
1462 using ResultType = Transform<typename Other::Scalar, Dim, Projective, Options>;
1463 static EIGEN_DEVICE_FUNC ResultType run(
const Other& other,
const TransformType& tr) {
1464 return ResultType(other * tr.matrix());
1469template <
typename Other,
int Options,
int Dim,
int HDim>
1470struct transform_left_product_impl<Other,
AffineCompact, Options, Dim, HDim, HDim, HDim> {
1471 using TransformType = Transform<typename Other::Scalar, Dim, AffineCompact, Options>;
1472 using MatrixType =
typename TransformType::MatrixType;
1473 using ResultType = Transform<typename Other::Scalar, Dim, Projective, Options>;
1474 static EIGEN_DEVICE_FUNC ResultType run(
const Other& other,
const TransformType& tr) {
1476 res.matrix().noalias() = other.template block<HDim, Dim>(0, 0) * tr.matrix();
1477 res.matrix().col(Dim) += other.col(Dim);
1483template <
typename Other,
int Mode,
int Options,
int Dim,
int HDim>
1484struct transform_left_product_impl<Other, Mode, Options, Dim, HDim, Dim, HDim> {
1485 using TransformType = Transform<typename Other::Scalar, Dim, Mode, Options>;
1486 using MatrixType =
typename TransformType::MatrixType;
1487 using ResultType = TransformType;
1488 static EIGEN_DEVICE_FUNC ResultType run(
const Other& other,
const TransformType& tr) {
1490 res.affine().noalias() = other * tr.matrix();
1491 res.matrix().row(Dim) = tr.matrix().row(Dim);
1497template <
typename Other,
int Options,
int Dim,
int HDim>
1498struct transform_left_product_impl<Other,
AffineCompact, Options, Dim, HDim, Dim, HDim> {
1499 using TransformType = Transform<typename Other::Scalar, Dim, AffineCompact, Options>;
1500 using MatrixType =
typename TransformType::MatrixType;
1501 using ResultType = TransformType;
1502 static EIGEN_DEVICE_FUNC ResultType run(
const Other& other,
const TransformType& tr) {
1504 res.matrix().noalias() = other.template block<Dim, Dim>(0, 0) * tr.matrix();
1505 res.translation() += other.col(Dim);
1511template <
typename Other,
int Mode,
int Options,
int Dim,
int HDim>
1512struct transform_left_product_impl<Other, Mode, Options, Dim, HDim, Dim, Dim> {
1513 using TransformType = Transform<typename Other::Scalar, Dim, Mode, Options>;
1514 using MatrixType =
typename TransformType::MatrixType;
1515 using ResultType = TransformType;
1516 static EIGEN_DEVICE_FUNC ResultType run(
const Other& other,
const TransformType& tr) {
1518 EIGEN_IF_CONSTEXPR (Mode !=
int(AffineCompact)) res.matrix().row(Dim) = tr.matrix().row(Dim);
1519 res.matrix().template topRows<Dim>().noalias() = other * tr.matrix().template topRows<Dim>();
1528template <
typename Scalar,
int Dim,
int LhsMode,
int LhsOptions,
int RhsMode,
int RhsOptions>
1529struct transform_transform_product_impl<Transform<Scalar, Dim, LhsMode, LhsOptions>,
1530 Transform<Scalar, Dim, RhsMode, RhsOptions>, false> {
1531 enum { ResultMode = transform_product_result<LhsMode, RhsMode>::Mode };
1532 using Lhs = Transform<Scalar, Dim, LhsMode, LhsOptions>;
1533 using Rhs = Transform<Scalar, Dim, RhsMode, RhsOptions>;
1534 using ResultType = Transform<Scalar, Dim, ResultMode, LhsOptions>;
1535 static EIGEN_DEVICE_FUNC ResultType run(
const Lhs& lhs,
const Rhs& rhs) {
1537 res.linear().noalias() = lhs.linear() * rhs.linear();
1538 res.translation().noalias() = lhs.linear() * rhs.translation() + lhs.translation();
1544template <
typename Scalar,
int Dim,
int LhsMode,
int LhsOptions,
int RhsMode,
int RhsOptions>
1545struct transform_transform_product_impl<Transform<Scalar, Dim, LhsMode, LhsOptions>,
1546 Transform<Scalar, Dim, RhsMode, RhsOptions>, true> {
1547 using Lhs = Transform<Scalar, Dim, LhsMode, LhsOptions>;
1548 using Rhs = Transform<Scalar, Dim, RhsMode, RhsOptions>;
1549 using ResultType = Transform<Scalar, Dim, Projective>;
1550 static EIGEN_DEVICE_FUNC ResultType run(
const Lhs& lhs,
const Rhs& rhs) {
1551 return ResultType(lhs.matrix() * rhs.matrix());
1555template <
typename Scalar,
int Dim,
int LhsOptions,
int RhsOptions>
1556struct transform_transform_product_impl<Transform<Scalar, Dim,
AffineCompact, LhsOptions>,
1557 Transform<Scalar, Dim,
Projective, RhsOptions>, true> {
1558 using Lhs = Transform<Scalar, Dim, AffineCompact, LhsOptions>;
1559 using Rhs = Transform<Scalar, Dim, Projective, RhsOptions>;
1560 using ResultType = Transform<Scalar, Dim, Projective>;
1561 static EIGEN_DEVICE_FUNC ResultType run(
const Lhs& lhs,
const Rhs& rhs) {
1563 res.matrix().template topRows<Dim>().noalias() = lhs.matrix() * rhs.matrix();
1564 res.matrix().row(Dim) = rhs.matrix().row(Dim);
1569template <
typename Scalar,
int Dim,
int LhsOptions,
int RhsOptions>
1570struct transform_transform_product_impl<Transform<Scalar, Dim,
Projective, LhsOptions>,
1572 using Lhs = Transform<Scalar, Dim, Projective, LhsOptions>;
1573 using Rhs = Transform<Scalar, Dim, AffineCompact, RhsOptions>;
1574 using ResultType = Transform<Scalar, Dim, Projective>;
1575 static EIGEN_DEVICE_FUNC ResultType run(
const Lhs& lhs,
const Rhs& rhs) {
1576 ResultType res(lhs.matrix().template leftCols<Dim>() * rhs.matrix());
1577 res.matrix().col(Dim) += lhs.matrix().col(Dim);
Expression of a fixed-size or dynamic-size block.
Definition Block.h:111
Base class for diagonal matrices and expressions.
Definition DiagonalMatrix.h:34
Two-sided Jacobi SVD decomposition of a rectangular matrix.
Definition JacobiSVD.h:613
Base class for all dense matrices, vectors, and expressions.
Definition MatrixBase.h:53
constexpr const DiagonalWrapper< const Derived > asDiagonal() const
Definition DiagonalMatrix.h:428
The matrix class, also used for vectors and row-vectors.
Definition Matrix.h:188
constexpr Scalar & coeffRef(Index rowId, Index colId)
Definition PlainObjectBase.h:205
Common base class for compact rotation representations.
Definition RotationBase.h:33
const SingularValuesType & singularValues() const
Definition SVDBase.h:203
const MatrixUType & matrixU() const
Definition SVDBase.h:176
const MatrixVType & matrixV() const
Definition SVDBase.h:192
Represents a translation transformation.
Definition Translation.h:34
TransformTraits
Definition Constants.h:470
@ DontAlign
Definition Constants.h:325
@ RowMajor
Definition Constants.h:321
@ Affine
Definition Constants.h:475
@ Projective
Definition Constants.h:479
@ AffineCompact
Definition Constants.h:477
@ Isometry
Definition Constants.h:472
constexpr unsigned int RowMajorBit
Definition Constants.h:71
Definition EigenBase.h:34
constexpr Derived & derived()
Definition EigenBase.h:50