12#ifndef EIGEN_TRANSFORM_H
13#define EIGEN_TRANSFORM_H
16#include "./InternalHeaderCheck.h"
22template <
typename Transform>
23struct transform_traits {
26 HDim = Transform::HDim,
27 Mode = Transform::Mode,
32template <
typename TransformType,
typename MatrixType,
33 int Case = transform_traits<TransformType>::IsProjective ? 0
34 : int(MatrixType::RowsAtCompileTime) == int(transform_traits<TransformType>::HDim) ? 1
36 int RhsCols = MatrixType::ColsAtCompileTime>
37struct transform_right_product_impl;
39template <
typename Other,
int Mode,
int Options,
int Dim,
int HDim,
int OtherRows = Other::RowsAtCompileTime,
40 int OtherCols = Other::ColsAtCompileTime>
41struct transform_left_product_impl;
43template <
typename Lhs,
typename Rhs,
44 bool AnyProjective = transform_traits<Lhs>::IsProjective || transform_traits<Rhs>::IsProjective>
45struct transform_transform_product_impl;
47template <
typename Other,
int Mode,
int Options,
int Dim,
int HDim,
int OtherRows = Other::RowsAtCompileTime,
48 int OtherCols = Other::ColsAtCompileTime>
49struct transform_construct_from_matrix;
51template <
typename TransformType>
52struct transform_take_affine_part;
54template <
typename Scalar_,
int Dim_,
int Mode_,
int Options_>
55struct traits<Transform<Scalar_, Dim_, Mode_, Options_> > {
56 typedef Scalar_ Scalar;
58 typedef Dense StorageKind;
60 Dim1 = Dim_ ==
Dynamic ? Dim_ : Dim_ + 1,
61 RowsAtCompileTime = Mode_ ==
Projective ? Dim1 : Dim_,
62 ColsAtCompileTime = Dim1,
63 MaxRowsAtCompileTime = RowsAtCompileTime,
64 MaxColsAtCompileTime = ColsAtCompileTime,
70struct transform_make_affine;
191template <
typename Scalar_,
int Dim_,
int Mode_,
int Options_>
208 typedef typename internal::make_proper_matrix_type<Scalar, Rows, HDim, Options>::type
MatrixType;
235 enum { TransformTimeDiagonalMode = ((Mode == int(
Isometry)) ?
Affine : int(Mode)) };
246 check_template_params();
252 check_template_params();
255 EIGEN_DEVICE_FUNC
inline explicit Transform(
const UniformScaling<Scalar>& s) {
256 check_template_params();
259 template <
typename Derived>
260 EIGEN_DEVICE_FUNC
inline explicit Transform(
const RotationBase<Derived, Dim>& r) {
261 check_template_params();
265 typedef internal::transform_take_affine_part<Transform> take_affine_part;
268 template <
typename OtherDerived>
271 (internal::is_same<Scalar, typename OtherDerived::Scalar>::value),
272 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY);
274 check_template_params();
275 internal::transform_construct_from_matrix<OtherDerived, Mode, Options, Dim, HDim>::run(
this, other.
derived());
279 template <
typename OtherDerived>
282 (internal::is_same<Scalar, typename OtherDerived::Scalar>::value),
283 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY);
285 internal::transform_construct_from_matrix<OtherDerived, Mode, Options, Dim, HDim>::run(
this, other.
derived());
289 template <
int OtherOptions>
291 check_template_params();
293 m_matrix = other.
matrix();
296 template <
int OtherMode,
int OtherOptions>
298 check_template_params();
301 EIGEN_STATIC_ASSERT(internal::check_implication(OtherMode ==
int(
Projective), Mode ==
int(
Projective)),
302 YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION)
308 YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION)
315 if (EIGEN_CONST_CONDITIONAL(ModeIsAffineCompact == OtherModeIsAffineCompact)) {
319 m_matrix.template block<Dim, Dim + 1>(0, 0) = other.matrix().template block<Dim, Dim + 1>(0, 0);
321 }
else if (EIGEN_CONST_CONDITIONAL(OtherModeIsAffineCompact)) {
323 internal::transform_construct_from_matrix<OtherMatrixType, Mode, Options, Dim, HDim>::run(
this, other.matrix());
328 linear() = other.linear();
333 template <
typename OtherDerived>
334 EIGEN_DEVICE_FUNC
Transform(
const ReturnByValue<OtherDerived>& other) {
335 check_template_params();
339 template <
typename OtherDerived>
345#ifdef EIGEN_QT_SUPPORT
346#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
349 inline QMatrix toQMatrix(
void)
const;
356 EIGEN_DEVICE_FUNC
constexpr Index rows() const noexcept {
357 return int(Mode) == int(
Projective) ? m_matrix.cols() : (m_matrix.cols() - 1);
359 EIGEN_DEVICE_FUNC
constexpr Index cols() const noexcept {
return m_matrix.cols(); }
414 template <
typename OtherDerived>
415 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const typename internal::transform_right_product_impl<
Transform,
416 OtherDerived>::ResultType
418 return internal::transform_right_product_impl<Transform, OtherDerived>::run(*
this, other.
derived());
428 template <
typename OtherDerived>
429 friend EIGEN_DEVICE_FUNC
inline const typename internal::transform_left_product_impl<OtherDerived, Mode, Options,
430 Dim_, Dim_ + 1>::ResultType
432 return internal::transform_left_product_impl<OtherDerived, Mode, Options, Dim, HDim>::run(a.
derived(), b);
441 template <
typename DiagonalDerived>
445 res.linearExt() *= b;
455 template <
typename DiagonalDerived>
465 template <
typename OtherDerived>
467 return *
this = *
this * other;
472 return internal::transform_transform_product_impl<Transform, Transform>::run(*
this, other);
485 template <
int OtherMode,
int OtherOptions>
486 struct icc_11_workaround {
487 typedef internal::transform_transform_product_impl<Transform, Transform<Scalar, Dim, OtherMode, OtherOptions> >
489 typedef typename ProductType::ResultType ResultType;
494 template <
int OtherMode,
int OtherOptions>
495 inline typename icc_11_workaround<OtherMode, OtherOptions>::ResultType
operator*(
497 typedef typename icc_11_workaround<OtherMode, OtherOptions>::ProductType ProductType;
498 return ProductType::run(*
this, other);
502 template <
int OtherMode,
int OtherOptions>
503 EIGEN_DEVICE_FUNC
inline
504 typename internal::transform_transform_product_impl<
Transform,
507 return internal::transform_transform_product_impl<Transform, Transform<Scalar, Dim, OtherMode, OtherOptions> >::run(
521 template <
typename OtherDerived>
524 template <
typename OtherDerived>
530 template <
typename OtherDerived>
533 template <
typename OtherDerived>
536 template <
typename RotationType>
539 template <
typename RotationType>
557 res.scale(s.factor());
561 EIGEN_DEVICE_FUNC
inline Transform& operator*=(
const DiagonalMatrix<Scalar, Dim>& s) {
566 template <
typename Derived>
568 template <
typename Derived>
569 EIGEN_DEVICE_FUNC
inline Transform& operator*=(
const RotationBase<Derived, Dim>& r) {
570 return rotate(r.toRotationMatrix());
572 template <
typename Derived>
573 EIGEN_DEVICE_FUNC
inline Transform operator*(
const RotationBase<Derived, Dim>& r)
const;
576 EIGEN_DEVICE_FUNC RotationReturnType
rotation()
const;
578 template <
typename RotationMatrixType,
typename ScalingMatrixType>
580 template <
typename ScalingMatrixType,
typename RotationMatrixType>
583 template <
typename PositionDerived,
typename OrientationType,
typename ScaleDerived>
585 const OrientationType& orientation,
591 EIGEN_DEVICE_FUNC
constexpr const Scalar*
data()
const {
return m_matrix.data(); }
593 EIGEN_DEVICE_FUNC
constexpr Scalar*
data() {
return m_matrix.data(); }
600 template <
typename NewScalarType>
601 EIGEN_DEVICE_FUNC
inline
602 typename internal::cast_return_type<Transform, Transform<NewScalarType, Dim, Mode, Options> >::type
604 return typename internal::cast_return_type<Transform, Transform<NewScalarType, Dim, Mode, Options> >::type(*
this);
608 template <
typename OtherScalarType>
610 check_template_params();
618 EIGEN_DEVICE_FUNC
bool isApprox(
const Transform& other,
const typename NumTraits<Scalar>::Real& prec =
619 NumTraits<Scalar>::dummy_precision())
const {
620 return m_matrix.isApprox(other.m_matrix, prec);
625 EIGEN_DEVICE_FUNC
void makeAffine() { internal::transform_make_affine<int(Mode)>::run(m_matrix); }
632 return m_matrix.template block < int(Mode) == int(Projective) ? HDim : Dim, Dim > (0, 0);
638 EIGEN_DEVICE_FUNC
inline const Block<
MatrixType, int(Mode) == int(
Projective) ? HDim : Dim, Dim> linearExt()
const {
639 return m_matrix.template block < int(Mode) == int(Projective) ? HDim : Dim, Dim > (0, 0);
646 EIGEN_DEVICE_FUNC
inline Block<
MatrixType, int(Mode) == int(
Projective) ? HDim : Dim, 1> translationExt() {
647 return m_matrix.template block < int(Mode) == int(Projective) ? HDim : Dim, 1 > (0, Dim);
653 EIGEN_DEVICE_FUNC
inline const Block<
MatrixType, int(Mode) == int(
Projective) ? HDim : Dim, 1> translationExt()
655 return m_matrix.template block < int(Mode) == int(Projective) ? HDim : Dim, 1 > (0, Dim);
658#ifdef EIGEN_TRANSFORM_PLUGIN
659#include EIGEN_TRANSFORM_PLUGIN
663#ifndef EIGEN_PARSED_BY_DOXYGEN
664 EIGEN_DEVICE_FUNC
static EIGEN_STRONG_INLINE
void check_template_params() {
665 EIGEN_STATIC_ASSERT((Options & (
DontAlign |
RowMajor)) == Options, INVALID_MATRIX_TEMPLATE_PARAMETERS)
710#ifdef EIGEN_QT_SUPPORT
712#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
717template <
typename Scalar,
int Dim,
int Mode,
int Options>
719 check_template_params();
727template <
typename Scalar,
int Dim,
int Mode,
int Options>
729 EIGEN_STATIC_ASSERT(Dim == 2, YOU_MADE_A_PROGRAMMING_MISTAKE)
731 m_matrix << other.m11(), other.m21(), other.dx(), other.m12(), other.m22(), other.dy();
733 m_matrix << other.m11(), other.m21(), other.dx(), other.m12(), other.m22(), other.dy(), 0, 0, 1;
743template <
typename Scalar,
int Dim,
int Mode,
int Options>
745 check_template_params();
746 EIGEN_STATIC_ASSERT(Dim == 2, YOU_MADE_A_PROGRAMMING_MISTAKE)
747 return QMatrix(m_matrix.
coeff(0, 0), m_matrix.
coeff(1, 0), m_matrix.
coeff(0, 1), m_matrix.
coeff(1, 1),
756template <
typename Scalar,
int Dim,
int Mode,
int Options>
758 check_template_params();
766template <
typename Scalar,
int Dim,
int Mode,
int Options>
768 check_template_params();
769 EIGEN_STATIC_ASSERT(Dim == 2, YOU_MADE_A_PROGRAMMING_MISTAKE)
771 m_matrix << other.m11(), other.m21(), other.dx(), other.m12(), other.m22(), other.dy();
773 m_matrix << other.m11(), other.m21(), other.dx(), other.m12(), other.m22(), other.dy(), other.m13(), other.m23(),
782template <
typename Scalar,
int Dim,
int Mode,
int Options>
784 EIGEN_STATIC_ASSERT(Dim == 2, YOU_MADE_A_PROGRAMMING_MISTAKE)
786 return QTransform(m_matrix.coeff(0, 0), m_matrix.coeff(1, 0), m_matrix.coeff(0, 1), m_matrix.coeff(1, 1),
787 m_matrix.coeff(0, 2), m_matrix.coeff(1, 2));
789 return QTransform(m_matrix.coeff(0, 0), m_matrix.coeff(1, 0), m_matrix.coeff(2, 0), m_matrix.coeff(0, 1),
790 m_matrix.coeff(1, 1), m_matrix.coeff(2, 1), m_matrix.coeff(0, 2), m_matrix.coeff(1, 2),
791 m_matrix.coeff(2, 2));
803template <
typename Scalar,
int Dim,
int Mode,
int Options>
804template <
typename OtherDerived>
807 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,
int(Dim))
808 EIGEN_STATIC_ASSERT(Mode !=
int(
Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
809 linearExt().noalias() = (linearExt() * other.
asDiagonal());
817template <
typename Scalar,
int Dim,
int Mode,
int Options>
820 EIGEN_STATIC_ASSERT(Mode !=
int(
Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
829template <
typename Scalar,
int Dim,
int Mode,
int Options>
830template <
typename OtherDerived>
833 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,
int(Dim))
834 EIGEN_STATIC_ASSERT(Mode !=
int(
Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
843template <
typename Scalar,
int Dim,
int Mode,
int Options>
846 EIGEN_STATIC_ASSERT(Mode !=
int(
Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
847 m_matrix.template topRows<Dim>() *= s;
855template <
typename Scalar,
int Dim,
int Mode,
int Options>
856template <
typename OtherDerived>
859 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,
int(Dim))
860 translationExt() += linearExt() * other;
868template <
typename Scalar,
int Dim,
int Mode,
int Options>
869template <
typename OtherDerived>
872 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,
int(Dim))
873 if (EIGEN_CONST_CONDITIONAL(
int(Mode) ==
int(
Projective)))
897template <
typename Scalar,
int Dim,
int Mode,
int Options>
898template <
typename RotationType>
901 linearExt() *= internal::toRotationMatrix<Scalar, Dim>(
rotation);
912template <
typename Scalar,
int Dim,
int Mode,
int Options>
913template <
typename RotationType>
916 m_matrix.template block<Dim, HDim>(0, 0) =
917 internal::toRotationMatrix<Scalar, Dim>(
rotation) * m_matrix.template block<Dim, HDim>(0, 0);
926template <
typename Scalar,
int Dim,
int Mode,
int Options>
929 EIGEN_STATIC_ASSERT(
int(Dim) == 2, YOU_MADE_A_PROGRAMMING_MISTAKE)
930 EIGEN_STATIC_ASSERT(Mode !=
int(
Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
941template <
typename Scalar,
int Dim,
int Mode,
int Options>
944 EIGEN_STATIC_ASSERT(
int(Dim) == 2, YOU_MADE_A_PROGRAMMING_MISTAKE)
945 EIGEN_STATIC_ASSERT(Mode !=
int(
Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
946 m_matrix.template block<Dim, HDim>(0, 0) =
947 LinearMatrixType({{1, sy}, {sx, 1}}) * m_matrix.template block<Dim, HDim>(0, 0);
955template <
typename Scalar,
int Dim,
int Mode,
int Options>
957 const TranslationType& t) {
959 translation() = t.vector();
964template <
typename Scalar,
int Dim,
int Mode,
int Options>
966 const TranslationType& t)
const {
967 Transform res = *
this;
968 res.translate(t.vector());
972template <
typename Scalar,
int Dim,
int Mode,
int Options>
976 linear().diagonal().fill(s.factor());
981template <
typename Scalar,
int Dim,
int Mode,
int Options>
982template <
typename Derived>
985 linear() = internal::toRotationMatrix<Scalar, Dim>(r);
986 translation().setZero();
991template <
typename Scalar,
int Dim,
int Mode,
int Options>
992template <
typename Derived>
996 res.rotate(r.derived());
1006struct transform_rotation_impl {
1007 template <
typename TransformType>
1008 EIGEN_DEVICE_FUNC
static inline const typename TransformType::LinearMatrixType run(
const TransformType& t) {
1009 typedef typename TransformType::LinearMatrixType LinearMatrixType;
1010 LinearMatrixType result;
1011 t.computeRotationScaling(&result, (LinearMatrixType*)0);
1016struct transform_rotation_impl<
Isometry> {
1017 template <
typename TransformType>
1018 EIGEN_DEVICE_FUNC
static inline typename TransformType::ConstLinearPart run(
const TransformType& t) {
1033template <
typename Scalar,
int Dim,
int Mode,
int Options>
1034EIGEN_DEVICE_FUNC
typename Transform<Scalar, Dim, Mode, Options>::RotationReturnType
1036 return internal::transform_rotation_impl<Mode>::run(*
this);
1050template <
typename Scalar,
int Dim,
int Mode,
int Options>
1051template <
typename RotationMatrixType,
typename ScalingMatrixType>
1053 ScalingMatrixType* scaling)
const {
1062 if (scaling) (*scaling).noalias() = svd.
matrixV() * sv.asDiagonal() * svd.
matrixV().adjoint();
1065 m.col(Dim - 1) *= x;
1066 (*rotation).noalias() = m * svd.
matrixV().adjoint();
1081template <
typename Scalar,
int Dim,
int Mode,
int Options>
1082template <
typename ScalingMatrixType,
typename RotationMatrixType>
1084 ScalingMatrixType* scaling, RotationMatrixType*
rotation)
const {
1093 if (scaling) *scaling = svd.
matrixU() * sv.asDiagonal() * svd.
matrixU().adjoint();
1096 m.col(Dim - 1) *= x;
1104template <
typename Scalar,
int Dim,
int Mode,
int Options>
1105template <
typename PositionDerived,
typename OrientationType,
typename ScaleDerived>
1108 const OrientationType& orientation,
1110 linear() = internal::toRotationMatrix<Scalar, Dim>(orientation);
1111 linear() *= scale.asDiagonal();
1120struct transform_make_affine {
1121 template <
typename MatrixType>
1122 EIGEN_DEVICE_FUNC
static void run(
MatrixType& mat) {
1123 static const int Dim = MatrixType::ColsAtCompileTime - 1;
1124 mat.template block<1, Dim>(Dim, 0).setZero();
1125 mat.coeffRef(Dim, Dim) =
typename MatrixType::Scalar(1);
1131 template <
typename MatrixType>
1132 EIGEN_DEVICE_FUNC
static void run(MatrixType&) {}
1136template <
typename TransformType,
int Mode = TransformType::Mode>
1137struct projective_transform_inverse {
1138 EIGEN_DEVICE_FUNC
static inline void run(
const TransformType&, TransformType&) {}
1141template <
typename TransformType>
1142struct projective_transform_inverse<TransformType,
Projective> {
1143 EIGEN_DEVICE_FUNC
static inline void run(
const TransformType& m, TransformType& res) {
1144 res.matrix() = m.matrix().inverse();
1170template <
typename Scalar,
int Dim,
int Mode,
int Options>
1175 internal::projective_transform_inverse<Transform>::run(*
this, res);
1178 res.
matrix().template topLeftCorner<Dim, Dim>() =
linear().transpose();
1179 }
else if (hint &
Affine) {
1180 res.
matrix().template topLeftCorner<Dim, Dim>() =
linear().inverse();
1182 eigen_assert(
false &&
"Invalid transform traits in Transform::Inverse");
1185 res.
matrix().template topRightCorner<Dim, 1>().noalias() =
1198template <
typename TransformType>
1199struct transform_take_affine_part {
1200 typedef typename TransformType::MatrixType
MatrixType;
1201 typedef typename TransformType::AffinePart AffinePart;
1202 typedef typename TransformType::ConstAffinePart ConstAffinePart;
1203 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE AffinePart run(
MatrixType& m) {
1204 return m.template block<TransformType::Dim, TransformType::HDim>(0, 0);
1206 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ConstAffinePart run(
const MatrixType& m) {
1207 return m.template block<TransformType::Dim, TransformType::HDim>(0, 0);
1211template <
typename Scalar,
int Dim,
int Options>
1212struct transform_take_affine_part<Transform<Scalar, Dim,
AffineCompact, Options> > {
1214 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE MatrixType& run(MatrixType& m) {
return m; }
1215 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const MatrixType& run(
const MatrixType& m) {
return m; }
1222template <
typename Other,
int Mode,
int Options,
int Dim,
int HDim>
1223struct transform_construct_from_matrix<Other, Mode, Options, Dim, HDim, Dim, Dim> {
1224 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void run(
1225 Transform<typename Other::Scalar, Dim, Mode, Options>* transform,
const Other& other) {
1226 transform->linear() = other;
1227 transform->translation().setZero();
1228 transform->makeAffine();
1232template <
typename Other,
int Mode,
int Options,
int Dim,
int HDim>
1233struct transform_construct_from_matrix<Other, Mode, Options, Dim, HDim, Dim, HDim> {
1234 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void run(
1235 Transform<typename Other::Scalar, Dim, Mode, Options>* transform,
const Other& other) {
1236 transform->affine() = other;
1237 transform->makeAffine();
1241template <
typename Other,
int Mode,
int Options,
int Dim,
int HDim>
1242struct transform_construct_from_matrix<Other, Mode, Options, Dim, HDim, HDim, HDim> {
1243 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void run(
1244 Transform<typename Other::Scalar, Dim, Mode, Options>* transform,
const Other& other) {
1245 transform->matrix() = other;
1249template <
typename Other,
int Options,
int Dim,
int HDim>
1250struct transform_construct_from_matrix<Other,
AffineCompact, Options, Dim, HDim, HDim, HDim> {
1251 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void run(
1252 Transform<typename Other::Scalar, Dim, AffineCompact, Options>* transform,
const Other& other) {
1253 transform->matrix() = other.template block<Dim, HDim>(0, 0);
1261template <
int LhsMode,
int RhsMode>
1262struct transform_product_result {
1272template <
typename TransformType,
typename MatrixType,
int RhsCols>
1273struct transform_right_product_impl<TransformType, MatrixType, 0, RhsCols> {
1274 typedef typename MatrixType::PlainObject ResultType;
1276 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ResultType run(
const TransformType& T,
const MatrixType& other) {
1277 return T.matrix() * other;
1281template <
typename TransformType,
typename MatrixType,
int RhsCols>
1282struct transform_right_product_impl<TransformType, MatrixType, 1, RhsCols> {
1284 Dim = TransformType::Dim,
1285 HDim = TransformType::HDim,
1286 OtherRows = MatrixType::RowsAtCompileTime,
1287 OtherCols = MatrixType::ColsAtCompileTime
1290 typedef typename MatrixType::PlainObject ResultType;
1292 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ResultType run(
const TransformType& T,
const MatrixType& other) {
1293 EIGEN_STATIC_ASSERT(OtherRows == HDim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);
1295 typedef Block<ResultType, Dim, OtherCols, int(MatrixType::RowsAtCompileTime) == Dim> TopLeftLhs;
1297 ResultType res(other.rows(), other.cols());
1298 TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() = T.affine() * other;
1299 res.row(OtherRows - 1) = other.row(OtherRows - 1);
1305template <
typename TransformType,
typename MatrixType,
int RhsCols>
1306struct transform_right_product_impl<TransformType, MatrixType, 2, RhsCols> {
1308 Dim = TransformType::Dim,
1309 HDim = TransformType::HDim,
1310 OtherRows = MatrixType::RowsAtCompileTime,
1311 OtherCols = MatrixType::ColsAtCompileTime
1314 typedef typename MatrixType::PlainObject ResultType;
1316 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ResultType run(
const TransformType& T,
const MatrixType& other) {
1317 EIGEN_STATIC_ASSERT(OtherRows == Dim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);
1319 typedef Block<ResultType, Dim, OtherCols, true> TopLeftLhs;
1321 Replicate<typename TransformType::ConstTranslationPart, 1, OtherCols>(T.translation(), 1, other.cols()));
1322 TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() += T.linear() * other;
1328template <
typename TransformType,
typename MatrixType>
1329struct transform_right_product_impl<TransformType, MatrixType, 2, 1>
1331 typedef typename TransformType::MatrixType TransformMatrix;
1333 Dim = TransformType::Dim,
1334 HDim = TransformType::HDim,
1335 OtherRows = MatrixType::RowsAtCompileTime,
1336 WorkingRows = plain_enum_min(TransformMatrix::RowsAtCompileTime, HDim)
1339 typedef typename MatrixType::PlainObject ResultType;
1341 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ResultType run(
const TransformType& T,
const MatrixType& other) {
1342 EIGEN_STATIC_ASSERT(OtherRows == Dim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);
1344 Matrix<typename ResultType::Scalar, Dim + 1, 1> rhs;
1345 rhs.template head<Dim>() = other;
1346 rhs[Dim] =
typename ResultType::Scalar(1);
1347 Matrix<typename ResultType::Scalar, WorkingRows, 1> res(T.matrix() * rhs);
1348 return res.template head<Dim>();
1357template <
typename Other,
int Mode,
int Options,
int Dim,
int HDim>
1358struct transform_left_product_impl<Other, Mode, Options, Dim, HDim, HDim, HDim> {
1359 typedef Transform<typename Other::Scalar, Dim, Mode, Options> TransformType;
1360 typedef typename TransformType::MatrixType MatrixType;
1361 typedef Transform<typename Other::Scalar, Dim, Projective, Options> ResultType;
1362 static EIGEN_DEVICE_FUNC ResultType run(
const Other& other,
const TransformType& tr) {
1363 return ResultType(other * tr.matrix());
1368template <
typename Other,
int Options,
int Dim,
int HDim>
1369struct transform_left_product_impl<Other,
AffineCompact, Options, Dim, HDim, HDim, HDim> {
1370 typedef Transform<typename Other::Scalar, Dim, AffineCompact, Options> TransformType;
1371 typedef typename TransformType::MatrixType MatrixType;
1372 typedef Transform<typename Other::Scalar, Dim, Projective, Options> ResultType;
1373 static EIGEN_DEVICE_FUNC ResultType run(
const Other& other,
const TransformType& tr) {
1375 res.matrix().noalias() = other.template block<HDim, Dim>(0, 0) * tr.matrix();
1376 res.matrix().col(Dim) += other.col(Dim);
1382template <
typename Other,
int Mode,
int Options,
int Dim,
int HDim>
1383struct transform_left_product_impl<Other, Mode, Options, Dim, HDim, Dim, HDim> {
1384 typedef Transform<typename Other::Scalar, Dim, Mode, Options> TransformType;
1385 typedef typename TransformType::MatrixType MatrixType;
1386 typedef TransformType ResultType;
1387 static EIGEN_DEVICE_FUNC ResultType run(
const Other& other,
const TransformType& tr) {
1389 res.affine().noalias() = other * tr.matrix();
1390 res.matrix().row(Dim) = tr.matrix().row(Dim);
1396template <
typename Other,
int Options,
int Dim,
int HDim>
1397struct transform_left_product_impl<Other,
AffineCompact, Options, Dim, HDim, Dim, HDim> {
1398 typedef Transform<typename Other::Scalar, Dim, AffineCompact, Options> TransformType;
1399 typedef typename TransformType::MatrixType MatrixType;
1400 typedef TransformType ResultType;
1401 static EIGEN_DEVICE_FUNC ResultType run(
const Other& other,
const TransformType& tr) {
1403 res.matrix().noalias() = other.template block<Dim, Dim>(0, 0) * tr.matrix();
1404 res.translation() += other.col(Dim);
1410template <
typename Other,
int Mode,
int Options,
int Dim,
int HDim>
1411struct transform_left_product_impl<Other, Mode, Options, Dim, HDim, Dim, Dim> {
1412 typedef Transform<typename Other::Scalar, Dim, Mode, Options> TransformType;
1413 typedef typename TransformType::MatrixType MatrixType;
1414 typedef TransformType ResultType;
1415 static EIGEN_DEVICE_FUNC ResultType run(
const Other& other,
const TransformType& tr) {
1417 if (Mode !=
int(AffineCompact)) res.matrix().row(Dim) = tr.matrix().row(Dim);
1418 res.matrix().template topRows<Dim>().noalias() = other * tr.matrix().template topRows<Dim>();
1427template <
typename Scalar,
int Dim,
int LhsMode,
int LhsOptions,
int RhsMode,
int RhsOptions>
1428struct transform_transform_product_impl<Transform<Scalar, Dim, LhsMode, LhsOptions>,
1429 Transform<Scalar, Dim, RhsMode, RhsOptions>, false> {
1430 enum { ResultMode = transform_product_result<LhsMode, RhsMode>::Mode };
1431 typedef Transform<Scalar, Dim, LhsMode, LhsOptions> Lhs;
1432 typedef Transform<Scalar, Dim, RhsMode, RhsOptions> Rhs;
1433 typedef Transform<Scalar, Dim, ResultMode, LhsOptions> ResultType;
1434 static EIGEN_DEVICE_FUNC ResultType run(
const Lhs& lhs,
const Rhs& rhs) {
1436 res.linear().noalias() = lhs.linear() * rhs.linear();
1437 res.translation() = lhs.linear() * rhs.translation() + lhs.translation();
1443template <
typename Scalar,
int Dim,
int LhsMode,
int LhsOptions,
int RhsMode,
int RhsOptions>
1444struct transform_transform_product_impl<Transform<Scalar, Dim, LhsMode, LhsOptions>,
1445 Transform<Scalar, Dim, RhsMode, RhsOptions>, true> {
1446 typedef Transform<Scalar, Dim, LhsMode, LhsOptions> Lhs;
1447 typedef Transform<Scalar, Dim, RhsMode, RhsOptions> Rhs;
1448 typedef Transform<Scalar, Dim, Projective> ResultType;
1449 static EIGEN_DEVICE_FUNC ResultType run(
const Lhs& lhs,
const Rhs& rhs) {
1450 return ResultType(lhs.matrix() * rhs.matrix());
1454template <
typename Scalar,
int Dim,
int LhsOptions,
int RhsOptions>
1455struct transform_transform_product_impl<Transform<Scalar, Dim,
AffineCompact, LhsOptions>,
1456 Transform<Scalar, Dim,
Projective, RhsOptions>, true> {
1457 typedef Transform<Scalar, Dim, AffineCompact, LhsOptions> Lhs;
1458 typedef Transform<Scalar, Dim, Projective, RhsOptions> Rhs;
1459 typedef Transform<Scalar, Dim, Projective> ResultType;
1460 static EIGEN_DEVICE_FUNC ResultType run(
const Lhs& lhs,
const Rhs& rhs) {
1462 res.matrix().template topRows<Dim>() = lhs.matrix() * rhs.matrix();
1463 res.matrix().row(Dim) = rhs.matrix().row(Dim);
1468template <
typename Scalar,
int Dim,
int LhsOptions,
int RhsOptions>
1469struct transform_transform_product_impl<Transform<Scalar, Dim,
Projective, LhsOptions>,
1471 typedef Transform<Scalar, Dim, Projective, LhsOptions> Lhs;
1472 typedef Transform<Scalar, Dim, AffineCompact, RhsOptions> Rhs;
1473 typedef Transform<Scalar, Dim, Projective> ResultType;
1474 static EIGEN_DEVICE_FUNC ResultType run(
const Lhs& lhs,
const Rhs& rhs) {
1475 ResultType res(lhs.matrix().template leftCols<Dim>() * rhs.matrix());
1476 res.matrix().col(Dim) += lhs.matrix().col(Dim);
Expression of a fixed-size or dynamic-size block.
Definition Block.h:110
RowXpr row(Index i)
Definition DenseBase.h:1085
Base class for diagonal matrices and expressions.
Definition DiagonalMatrix.h:33
Two-sided Jacobi SVD decomposition of a rectangular matrix.
Definition JacobiSVD.h:500
Base class for all dense matrices, vectors, and expressions.
Definition MatrixBase.h:52
const DiagonalWrapper< const Derived > asDiagonal() const
Definition DiagonalMatrix.h:347
The matrix class, also used for vectors and row-vectors.
Definition Matrix.h:186
constexpr Scalar & coeffRef(Index rowId, Index colId)
Definition PlainObjectBase.h:191
constexpr const Scalar & coeff(Index rowId, Index colId) const
Definition PlainObjectBase.h:172
Derived & setZero(Index size)
Definition CwiseNullaryOp.h:567
Common base class for compact rotation representations.
Definition RotationBase.h:32
const SingularValuesType & singularValues() const
Definition SVDBase.h:200
const MatrixUType & matrixU() const
Definition SVDBase.h:173
const MatrixVType & matrixV() const
Definition SVDBase.h:189
Represents a translation transformation.
Definition Translation.h:33
TransformTraits
Definition Constants.h:453
@ DontAlign
Definition Constants.h:324
@ RowMajor
Definition Constants.h:320
@ Affine
Definition Constants.h:458
@ Projective
Definition Constants.h:462
@ AffineCompact
Definition Constants.h:460
@ Isometry
Definition Constants.h:455
const unsigned int RowMajorBit
Definition Constants.h:70
Namespace containing all symbols from the Eigen library.
Definition B01_Experimental.dox:1
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:82
const int Dynamic
Definition Constants.h:25
Definition EigenBase.h:33
constexpr Derived & derived()
Definition EigenBase.h:49