From 236b7a545d139a32b6cd0984044ce91d737094a5 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Sat, 30 Aug 2008 12:42:06 +0000 Subject: update Transform::inverse() to take an optional argument stating whether the transformation is: NonAffine, Affine (default), contains NoShear, contains NoScaling that allows significant speed improvements. If you like it, this concept could be applied to Transform::extractRotation (or to a more advanced decomposition function) and to Hyperplane::transformed() and maybe to some other places... e.g., I think a Transform::normalMatrix() function would not harm and warn user that the transformation of normals is not that trivial (I saw this mistake much too often) --- Eigen/Geometry | 1 + Eigen/src/Geometry/Scaling.h | 9 +++- Eigen/src/Geometry/Transform.h | 109 +++++++++++++++++++++++++++++++++++++-- Eigen/src/Geometry/Translation.h | 7 ++- 4 files changed, 120 insertions(+), 6 deletions(-) (limited to 'Eigen') diff --git a/Eigen/Geometry b/Eigen/Geometry index b5037306d..ab3a9b9d6 100644 --- a/Eigen/Geometry +++ b/Eigen/Geometry @@ -25,6 +25,7 @@ namespace Eigen { // the Geometry module use cwiseCos and cwiseSin which are defined in the Array module #include "src/Array/CwiseOperators.h" #include "src/Array/Functors.h" +#include "src/Array/PartialRedux.h" #include "src/Geometry/OrthoMethods.h" #include "src/Geometry/Quaternion.h" diff --git a/Eigen/src/Geometry/Scaling.h b/Eigen/src/Geometry/Scaling.h index fcf1c0437..73938ac8b 100644 --- a/Eigen/src/Geometry/Scaling.h +++ b/Eigen/src/Geometry/Scaling.h @@ -35,18 +35,23 @@ * \param _Dim the dimension of the space, can be a compile time value or Dynamic * * - * \sa class Translate, class Transform + * \sa class Translation, class Transform */ template class Scaling { public: + /** dimension of the space */ enum { Dim = _Dim }; /** the scalar type of the coefficients */ typedef _Scalar Scalar; - typedef Matrix LinearMatrixType; + /** corresponding vector type */ typedef Matrix VectorType; + /** corresponding linear transformation matrix type */ + typedef Matrix LinearMatrixType; + /** corresponding translation type */ typedef Translation TranslationType; + /** corresponding affine transformation type */ typedef Transform TransformType; protected: diff --git a/Eigen/src/Geometry/Transform.h b/Eigen/src/Geometry/Transform.h index f32577e88..fd5fd66ba 100644 --- a/Eigen/src/Geometry/Transform.h +++ b/Eigen/src/Geometry/Transform.h @@ -25,6 +25,14 @@ #ifndef EIGEN_TRANSFORM_H #define EIGEN_TRANSFORM_H +/** Represents some traits of a transformation */ +enum TransformationKnowledge { + NoScaling, ///< the transformation is a concatenation of translations, rotations + NoShear, ///< the transformation is a concatenation of translations, rotations and scalings + GenericAffine, ///< the transformation is affine (linear transformation + translation) + NonAffine ///< the transformation might not be affine +}; + // Note that we have to pass Dim and HDim because it is not allowed to use a template // parameter to define a template specialization. To be more precise, in the following // specializations, it is not allowed to use Dim+1 instead of HDim. @@ -73,7 +81,9 @@ public: typedef Matrix VectorType; /** type of a read/write reference to the translation part of the rotation */ typedef Block TranslationPart; + /** corresponding translation type */ typedef Translation TranslationType; + /** corresponding scaling transformation type */ typedef Scaling ScalingType; protected: @@ -193,8 +203,11 @@ public: Transform& shear(Scalar sx, Scalar sy); Transform& preshear(Scalar sx, Scalar sy); + inline Transform& operator=(const TranslationType& t); inline Transform& operator*=(const TranslationType& t) { return translate(t.vector()); } inline Transform operator*(const TranslationType& t) const; + + inline Transform& operator=(const ScalingType& t); inline Transform& operator*=(const ScalingType& s) { return scale(s.coeffs()); } inline Transform operator*(const ScalingType& s) const; friend inline Transform operator*(const LinearMatrixType& mat, const Transform& t) @@ -212,9 +225,7 @@ public: Transform& fromPositionOrientationScale(const MatrixBase &position, const OrientationType& orientation, const MatrixBase &scale); - /** \sa MatrixBase::inverse() */ - const MatrixType inverse() const - { return m_matrix.inverse(); } + inline const MatrixType inverse(TransformationKnowledge knowledge = GenericAffine) const; const Scalar* data() const { return m_matrix.data(); } Scalar* data() { return m_matrix.data(); } @@ -232,6 +243,10 @@ typedef Transform Transform2d; /** \ingroup GeometryModule */ typedef Transform Transform3d; +/************************** +*** Optional QT support *** +**************************/ + #ifdef EIGEN_QT_SUPPORT /** Initialises \c *this from a QMatrix assuming the dimension is 2. * @@ -271,6 +286,10 @@ QMatrix Transform::toQMatrix(void) const } #endif +/********************* +*** Procedural API *** +*********************/ + /** Applies on the right the non uniform scale transformation represented * by the vector \a other to \c *this and returns a reference to \c *this. * \sa prescale() @@ -399,6 +418,18 @@ Transform::preshear(Scalar sx, Scalar sy) return *this; } +/****************************************************** +*** Scaling, Translation and Rotation compatibility *** +******************************************************/ + +template +inline Transform& Transform::operator=(const TranslationType& t) +{ + setIdentity(); + translation() = t.vector(); + return *this; +} + template inline Transform Transform::operator*(const TranslationType& t) const { @@ -407,6 +438,15 @@ inline Transform Transform::operator*(const TranslationT return res; } +template +inline Transform& Transform::operator=(const ScalingType& s) +{ + m_matrix.setZero(); + linear().diagonal() = s.coeffs(); + m_matrix(Dim,Dim) = Scalar(1); + return *this; +} + template inline Transform Transform::operator*(const ScalingType& s) const { @@ -415,6 +455,10 @@ inline Transform Transform::operator*(const ScalingType& return res; } +/*************************** +*** Specialial functions *** +***************************/ + /** \returns the rotation part of the transformation using a QR decomposition. * \sa extractRotationNoShear(), class QR */ @@ -454,6 +498,65 @@ Transform::fromPositionOrientationScale(const MatrixBase +inline const typename Transform::MatrixType +Transform::inverse(TransformationKnowledge knowledge) const +{ + if (knowledge == NonAffine) + { + return m_matrix.inverse(); + } + else + { + MatrixType res; + if (knowledge == GenericAffine) + { + res.template corner(TopLeft) = linear().inverse(); + } + else if (knowledge == NoShear) + { + // extract linear = rotation * scaling + // then inv(linear) = inv(scaling) * inv(rotation) + // = inv(scaling) * trans(rotation) + // = inv(scaling) * trans(inv(scaling)) * trans(A) + // = inv(scaling) * inv(scaling) * trans(A) + // = inv(scaling)^2 * trans(A) + // = scaling^-2 * trans(A) + // with scaling[i] = A.col(i).norm() + VectorType invScaling2 = linear().colwise().norm2().cwise().inverse(); + res.template corner(TopLeft) = (invScaling2.asDiagonal() * linear().transpose()).lazy(); + } + else if (knowledge == NoScaling) + { + res.template corner(TopLeft) = linear().transpose(); + } + else + { + ei_assert("invalid knowledge value in Transform::inverse()"); + } + // translation and remaining parts + res.template corner(TopRight) = - res.template corner(TopLeft) * translation(); + res.template corner<1,Dim>(BottomLeft).setZero(); + res.coeffRef(Dim,Dim) = Scalar(1); + return res; + } +} + /*********************************** *** Specializations of operator* *** ***********************************/ diff --git a/Eigen/src/Geometry/Translation.h b/Eigen/src/Geometry/Translation.h index ad63b835f..b65aca9eb 100644 --- a/Eigen/src/Geometry/Translation.h +++ b/Eigen/src/Geometry/Translation.h @@ -41,12 +41,17 @@ template class Translation { public: + /** dimension of the space */ enum { Dim = _Dim }; /** the scalar type of the coefficients */ typedef _Scalar Scalar; - typedef Matrix LinearMatrixType; + /** corresponding vector type */ typedef Matrix VectorType; + /** corresponding linear transformation matrix type */ + typedef Matrix LinearMatrixType; + /** corresponding scaling transformation type */ typedef Scaling ScalingType; + /** corresponding affine transformation type */ typedef Transform TransformType; protected: -- cgit v1.2.3