diff options
author | Gael Guennebaud <g.gael@free.fr> | 2009-01-28 16:26:06 +0000 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2009-01-28 16:26:06 +0000 |
commit | 1b194193efeb9eb1930993e53d65404f2fdd54a1 (patch) | |
tree | ab15b3c5d2c09cc3041ca3241bd29f3246dff720 /Eigen | |
parent | da555585e27f770bad3dc85ddeaf51df5a582416 (diff) |
Big change in DiagonalMatrix and Geometry/Scaling:
* previous DiagonalMatrix expression is now DiagonalMatrixWrapper
* DiagonalMatrix class is now for storage
* add the DiagonalMatrixBase class to factorize code of the
two previous classes
* remove Scaling class (it is now a global function)
* add UniformScaling helper class
(don't use it directly, use the Scaling function)
* add the Scaling global function to simplify the creation
of scaling objects
There is still a lot to do, in particular about DiagonalProduct for which
the goal is to get rid of the "if()" in the coeff() function. At least
it is not worse than before ! Also need to uptade the tutorial and add more doc.
Diffstat (limited to 'Eigen')
-rw-r--r-- | Eigen/src/Core/DiagonalMatrix.h | 244 | ||||
-rw-r--r-- | Eigen/src/Core/DiagonalProduct.h | 6 | ||||
-rw-r--r-- | Eigen/src/Core/MatrixBase.h | 2 | ||||
-rw-r--r-- | Eigen/src/Core/NestByValue.h | 2 | ||||
-rw-r--r-- | Eigen/src/Core/util/ForwardDeclarations.h | 6 | ||||
-rw-r--r-- | Eigen/src/Core/util/StaticAssert.h | 3 | ||||
-rw-r--r-- | Eigen/src/Geometry/Quaternion.h | 9 | ||||
-rw-r--r-- | Eigen/src/Geometry/RotationBase.h | 16 | ||||
-rw-r--r-- | Eigen/src/Geometry/Scaling.h | 182 | ||||
-rw-r--r-- | Eigen/src/Geometry/Transform.h | 120 | ||||
-rw-r--r-- | Eigen/src/Geometry/Translation.h | 31 |
11 files changed, 410 insertions, 211 deletions
diff --git a/Eigen/src/Core/DiagonalMatrix.h b/Eigen/src/Core/DiagonalMatrix.h index 07eaf0747..975a80bd3 100644 --- a/Eigen/src/Core/DiagonalMatrix.h +++ b/Eigen/src/Core/DiagonalMatrix.h @@ -25,22 +25,208 @@ #ifndef EIGEN_DIAGONALMATRIX_H #define EIGEN_DIAGONALMATRIX_H + +template<typename CoeffsVectorType, typename Derived> +class DiagonalMatrixBase : ei_no_assignment_operator, + public MatrixBase<Derived> +{ + public: + typedef MatrixBase<Derived> Base; + typedef typename ei_traits<Derived>::Scalar Scalar; + typedef typename Base::PacketScalar PacketScalar; + using Base::derived; + + protected: + typedef typename ei_cleantype<CoeffsVectorType>::type _CoeffsVectorType; + + /** Default constructor without initialization */ + inline DiagonalMatrixBase() {} + /** Constructs a diagonal matrix with given dimension */ + inline DiagonalMatrixBase(int dim) : m_coeffs(dim) {} + /** Generic constructor from an expression */ + template<typename OtherDerived> + inline DiagonalMatrixBase(const MatrixBase<OtherDerived>& other) + { + construct_from_expression<OtherDerived>::run(derived(),other.derived()); + } + + template<typename OtherDerived, + bool IsVector = OtherDerived::IsVectorAtCompileTime, + bool IsDiagonal = (OtherDerived::Flags&Diagonal)==Diagonal> + struct construct_from_expression; + + // = vector + template<typename OtherDerived> + struct construct_from_expression<OtherDerived,true,false> + { + static void run(Derived& dst, const OtherDerived& src) + { dst.m_coeffs = src; } + }; + + // = diagonal + template<typename OtherDerived, bool IsVector> + struct construct_from_expression<OtherDerived,IsVector,true> + { + static void run(Derived& dst, const OtherDerived& src) + { dst.m_coeffs = src.diagonal(); } + }; + + public: + + inline DiagonalMatrixBase(const _CoeffsVectorType& coeffs) : m_coeffs(coeffs) + { + EIGEN_STATIC_ASSERT_VECTOR_ONLY(_CoeffsVectorType); + ei_assert(coeffs.size() > 0); + } + + template<typename OtherDerived, bool IsVector=OtherDerived::IsVectorAtCompileTime> + struct ei_diagonal_product_ctor { + static void run(DiagonalMatrixBase& dst, const OtherDerived& src) + { dst.m_coeffs = src; } + }; + + template<typename OtherDerived> + struct ei_diagonal_product_ctor<OtherDerived,false> { + static void run(DiagonalMatrixBase& dst, const OtherDerived& src) + { + EIGEN_STATIC_ASSERT((OtherDerived::Flags&Diagonal)==Diagonal, THIS_METHOD_IS_ONLY_FOR_DIAGONAL_MATRIX); + dst.m_coeffs = src.diagonal(); + } + }; + + template<typename NewType> + inline DiagonalMatrixWrapper<NestByValue<CwiseUnaryOp<ei_scalar_cast_op<Scalar, NewType>, _CoeffsVectorType> > > cast() const + { + return m_coeffs.template cast<NewType>().nestByValue().asDiagonal(); + } + + /** Assignment operator. + * The right-hand-side \a other must be either a vector representing the diagonal + * coefficients or a diagonal matrix expression. + */ + template<typename OtherDerived> + inline Derived& operator=(const MatrixBase<OtherDerived>& other) + { + construct_from_expression<OtherDerived>::run(derived(),other); + return derived(); + } + + inline int rows() const { return m_coeffs.size(); } + inline int cols() const { return m_coeffs.size(); } + + inline const Scalar coeff(int row, int col) const + { + return row == col ? m_coeffs.coeff(row) : static_cast<Scalar>(0); + } + + inline const Scalar coeffRef(int row, int col) const + { + ei_assert(row==col); + return m_coeffs.coeffRef(row); + } + + inline _CoeffsVectorType& diagonal() { return m_coeffs; } + inline const _CoeffsVectorType& diagonal() const { return m_coeffs; } + + protected: + CoeffsVectorType m_coeffs; +}; + /** \class DiagonalMatrix - * \nonstableyet + * \nonstableyet + * + * \brief Represent a diagonal matrix with its storage + * + * \param _Scalar the type of coefficients + * \param _Size the dimension of the matrix + * + * \sa class Matrix + */ +template<typename _Scalar,int _Size> +struct ei_traits<DiagonalMatrix<_Scalar,_Size> > : ei_traits<Matrix<_Scalar,_Size,_Size> > +{ + enum { + Flags = (ei_traits<Matrix<_Scalar,_Size,_Size> >::Flags & HereditaryBits) | Diagonal + }; +}; + +template<typename _Scalar, int _Size> +class DiagonalMatrix + : public DiagonalMatrixBase<Matrix<_Scalar,_Size,1>, DiagonalMatrix<_Scalar,_Size> > +{ + public: + EIGEN_GENERIC_PUBLIC_INTERFACE(DiagonalMatrix) + typedef DiagonalMatrixBase<Matrix<_Scalar,_Size,1>, DiagonalMatrix<_Scalar,_Size> > DiagonalBase; + + protected: + typedef Matrix<_Scalar,_Size,1> CoeffVectorType; + using DiagonalBase::m_coeffs; + + public: + + /** Default constructor without initialization */ + inline DiagonalMatrix() : DiagonalBase() + {} + + /** Constructs a diagonal matrix with given dimension */ + inline DiagonalMatrix(int dim) : DiagonalBase(dim) + {} + + /** 2D only */ + inline DiagonalMatrix(const Scalar& sx, const Scalar& sy) + { + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(DiagonalMatrix,2,2); + m_coeffs.x() = sx; + m_coeffs.y() = sy; + } + /** 3D only */ + inline DiagonalMatrix(const Scalar& sx, const Scalar& sy, const Scalar& sz) + { + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(DiagonalMatrix,3,3); + m_coeffs.x() = sx; + m_coeffs.y() = sy; + m_coeffs.z() = sz; + } + + /** copy constructor */ + inline DiagonalMatrix(const DiagonalMatrix& other) : DiagonalBase(other.m_coeffs) + {} + + /** generic constructor from expression */ + template<typename OtherDerived> + explicit inline DiagonalMatrix(const MatrixBase<OtherDerived>& other) : DiagonalBase(other) + {} + + DiagonalMatrix& operator=(const DiagonalMatrix& other) + { + m_coeffs = other.m_coeffs; + return *this; + } + + template<typename OtherDerived> + DiagonalMatrix& operator=(const MatrixBase<OtherDerived>& other) + { + EIGEN_STATIC_ASSERT((OtherDerived::Flags&Diagonal)==Diagonal, THIS_METHOD_IS_ONLY_FOR_DIAGONAL_MATRIX); + m_coeffs = other.diagonal(); + return *this; + } +}; + +/** \class DiagonalMatrixWrapper + * \nonstableyet * * \brief Expression of a diagonal matrix * * \param CoeffsVectorType the type of the vector of diagonal coefficients * * This class is an expression of a diagonal matrix with given vector of diagonal - * coefficients. It is the return - * type of MatrixBase::diagonal(const OtherDerived&) and most of the time this is - * the only way it is used. + * coefficients. It is the return type of MatrixBase::diagonal(const OtherDerived&) + * and most of the time this is the only way it is used. * - * \sa MatrixBase::diagonal(const OtherDerived&) + * \sa class DiagonalMatrixBase, class DiagonalMatrix, MatrixBase::asDiagonal() */ template<typename CoeffsVectorType> -struct ei_traits<DiagonalMatrix<CoeffsVectorType> > +struct ei_traits<DiagonalMatrixWrapper<CoeffsVectorType> > { typedef typename CoeffsVectorType::Scalar Scalar; typedef typename ei_nested<CoeffsVectorType>::type CoeffsVectorTypeNested; @@ -54,45 +240,19 @@ struct ei_traits<DiagonalMatrix<CoeffsVectorType> > CoeffReadCost = _CoeffsVectorTypeNested::CoeffReadCost }; }; - template<typename CoeffsVectorType> -class DiagonalMatrix : ei_no_assignment_operator, - public MatrixBase<DiagonalMatrix<CoeffsVectorType> > +class DiagonalMatrixWrapper + : public DiagonalMatrixBase<typename CoeffsVectorType::Nested, DiagonalMatrixWrapper<CoeffsVectorType> > { + typedef typename CoeffsVectorType::Nested CoeffsVectorTypeNested; + typedef DiagonalMatrixBase<CoeffsVectorTypeNested, DiagonalMatrixWrapper<CoeffsVectorType> > DiagonalBase; public: - - EIGEN_GENERIC_PUBLIC_INTERFACE(DiagonalMatrix) - - // needed to evaluate a DiagonalMatrix<Xpr> to a DiagonalMatrix<NestByValue<Vector> > - template<typename OtherCoeffsVectorType> - inline DiagonalMatrix(const DiagonalMatrix<OtherCoeffsVectorType>& other) : m_coeffs(other.diagonal()) - { - EIGEN_STATIC_ASSERT_VECTOR_ONLY(CoeffsVectorType); - EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherCoeffsVectorType); - ei_assert(m_coeffs.size() > 0); - } - - inline DiagonalMatrix(const CoeffsVectorType& coeffs) : m_coeffs(coeffs) - { - EIGEN_STATIC_ASSERT_VECTOR_ONLY(CoeffsVectorType); - ei_assert(coeffs.size() > 0); - } - - inline int rows() const { return m_coeffs.size(); } - inline int cols() const { return m_coeffs.size(); } - - inline const Scalar coeff(int row, int col) const - { - return row == col ? m_coeffs.coeff(row) : static_cast<Scalar>(0); - } - - inline const CoeffsVectorType& diagonal() const { return m_coeffs; } - - protected: - const typename CoeffsVectorType::Nested m_coeffs; + EIGEN_GENERIC_PUBLIC_INTERFACE(DiagonalMatrixWrapper) + inline DiagonalMatrixWrapper(const CoeffsVectorType& coeffs) : DiagonalBase(coeffs) + {} }; -/** \nonstableyet +/** \nonstableyet * \returns an expression of a diagonal matrix with *this as vector of diagonal coefficients * * \only_for_vectors @@ -105,13 +265,13 @@ class DiagonalMatrix : ei_no_assignment_operator, * \sa class DiagonalMatrix, isDiagonal() **/ template<typename Derived> -inline const DiagonalMatrix<Derived> +inline const DiagonalMatrixWrapper<Derived> MatrixBase<Derived>::asDiagonal() const { return derived(); } -/** \nonstableyet +/** \nonstableyet * \returns true if *this is approximately equal to a diagonal matrix, * within the precision given by \a prec. * diff --git a/Eigen/src/Core/DiagonalProduct.h b/Eigen/src/Core/DiagonalProduct.h index f33a26f98..83ba96c3c 100644 --- a/Eigen/src/Core/DiagonalProduct.h +++ b/Eigen/src/Core/DiagonalProduct.h @@ -30,9 +30,9 @@ * Unlike ei_nested, if the argument is a DiagonalMatrix and if it must be evaluated, * then it evaluated to a DiagonalMatrix having its own argument evaluated. */ -template<typename T, int N> struct ei_nested_diagonal : ei_nested<T,N> {}; -template<typename T, int N> struct ei_nested_diagonal<DiagonalMatrix<T>,N > - : ei_nested<DiagonalMatrix<T>, N, DiagonalMatrix<NestByValue<typename ei_plain_matrix_type<T>::type> > > +template<typename T, int N, bool IsDiagonal = (T::Flags&Diagonal)==Diagonal> struct ei_nested_diagonal : ei_nested<T,N> {}; +template<typename T, int N> struct ei_nested_diagonal<T,N,true> + : ei_nested<T, N, DiagonalMatrix<typename T::Scalar, EIGEN_ENUM_MIN(T::RowsAtCompileTime,T::ColsAtCompileTime)> > {}; // specialization of ProductReturnType diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index 1fd02b0af..4dd319985 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -443,7 +443,7 @@ template<typename Derived> class MatrixBase static const BasisReturnType UnitZ(); static const BasisReturnType UnitW(); - const DiagonalMatrix<Derived> asDiagonal() const; + const DiagonalMatrixWrapper<Derived> asDiagonal() const; void fill(const Scalar& value); Derived& setConstant(const Scalar& value); diff --git a/Eigen/src/Core/NestByValue.h b/Eigen/src/Core/NestByValue.h index da79315bf..dfe757447 100644 --- a/Eigen/src/Core/NestByValue.h +++ b/Eigen/src/Core/NestByValue.h @@ -97,6 +97,8 @@ template<typename ExpressionType> class NestByValue { m_expression.const_cast_derived().template writePacket<LoadMode>(index, x); } + + operator const ExpressionType&() const { return m_expression; } protected: const ExpressionType m_expression; diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h index a72a40b1b..83c42442b 100644 --- a/Eigen/src/Core/util/ForwardDeclarations.h +++ b/Eigen/src/Core/util/ForwardDeclarations.h @@ -45,7 +45,9 @@ template<typename NullaryOp, typename MatrixType> class CwiseNullaryOp; template<typename UnaryOp, typename MatrixType> class CwiseUnaryOp; template<typename BinaryOp, typename Lhs, typename Rhs> class CwiseBinaryOp; template<typename Lhs, typename Rhs, int ProductMode> class Product; -template<typename CoeffsVectorType> class DiagonalMatrix; +template<typename CoeffsVectorType, typename Derived> class DiagonalMatrixBase; +template<typename CoeffsVectorType> class DiagonalMatrixWrapper; +template<typename _Scalar, int _Size> class DiagonalMatrix; template<typename MatrixType> class DiagonalCoeffs; template<typename MatrixType, int PacketAccess = AsRequested> class Map; template<typename MatrixType, unsigned int Mode> class Part; @@ -117,7 +119,7 @@ template<typename Scalar,int Dim> class Transform; template <typename _Scalar, int _AmbientDim> class ParametrizedLine; template <typename _Scalar, int _AmbientDim> class Hyperplane; template<typename Scalar,int Dim> class Translation; -template<typename Scalar,int Dim> class Scaling; +template<typename Scalar> class UniformScaling; // Sparse module: template<typename Lhs, typename Rhs, int ProductMode> class SparseProduct; diff --git a/Eigen/src/Core/util/StaticAssert.h b/Eigen/src/Core/util/StaticAssert.h index 7ceeabb5f..2c13098a2 100644 --- a/Eigen/src/Core/util/StaticAssert.h +++ b/Eigen/src/Core/util/StaticAssert.h @@ -74,7 +74,8 @@ THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES, THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES, INVALID_MATRIX_TEMPLATE_PARAMETERS, - BOTH_MATRICES_MUST_HAVE_THE_SAME_STORAGE_ORDER + BOTH_MATRICES_MUST_HAVE_THE_SAME_STORAGE_ORDER, + THIS_METHOD_IS_ONLY_FOR_DIAGONAL_MATRIX }; }; diff --git a/Eigen/src/Geometry/Quaternion.h b/Eigen/src/Geometry/Quaternion.h index 9504962d5..71bf13297 100644 --- a/Eigen/src/Geometry/Quaternion.h +++ b/Eigen/src/Geometry/Quaternion.h @@ -193,8 +193,7 @@ public: Quaternion slerp(Scalar t, const Quaternion& other) const; - template<typename Derived> - Vector3 operator* (const MatrixBase<Derived>& vec) const; + Vector3 operator* (const Vector3& vec) const; /** \returns \c *this with scalar type casted to \a NewScalarType * @@ -256,17 +255,15 @@ inline Quaternion<Scalar>& Quaternion<Scalar>::operator*= (const Quaternion& oth * - Via a Matrix3: 24 + 15n */ template <typename Scalar> -template<typename Derived> inline typename Quaternion<Scalar>::Vector3 -Quaternion<Scalar>::operator* (const MatrixBase<Derived>& v) const +Quaternion<Scalar>::operator* (const Vector3& v) const { // Note that this algorithm comes from the optimization by hand // of the conversion to a Matrix followed by a Matrix/Vector product. // It appears to be much faster than the common algorithm found // in the litterature (30 versus 39 flops). It also requires two // Vector3 as temporaries. - Vector3 uv; - uv = 2 * this->vec().cross(v); + Vector3 uv = Scalar(2) * this->vec().cross(v); return v + this->w() * uv + this->vec().cross(uv); } diff --git a/Eigen/src/Geometry/RotationBase.h b/Eigen/src/Geometry/RotationBase.h index 5fec0f18d..9d5f16e3f 100644 --- a/Eigen/src/Geometry/RotationBase.h +++ b/Eigen/src/Geometry/RotationBase.h @@ -59,9 +59,19 @@ class RotationBase inline Transform<Scalar,Dim> operator*(const Translation<Scalar,Dim>& t) const { return toRotationMatrix() * t; } - /** \returns the concatenation of the rotation \c *this with a scaling \a s */ - inline RotationMatrixType operator*(const Scaling<Scalar,Dim>& s) const - { return toRotationMatrix() * s; } + /** \returns the concatenation of the rotation \c *this with a uniform scaling \a s */ + inline RotationMatrixType operator*(const UniformScaling<Scalar>& s) const + { return toRotationMatrix() * s.factor(); } + + /** \returns the concatenation of the rotation \c *this with a linear transformation \a l */ + template<typename OtherDerived> + inline RotationMatrixType operator*(const MatrixBase<OtherDerived>& l) const + { return toRotationMatrix() * l.derived(); } + + /** \returns the concatenation of a linear transformation \a l with the rotation \a r */ + template<typename OtherDerived> friend + inline RotationMatrixType operator*(const MatrixBase<OtherDerived>& l, const Derived& r) + { return l.derived() * r.toRotationMatrix(); } /** \returns the concatenation of the rotation \c *this with an affine transformation \a t */ inline Transform<Scalar,Dim> operator*(const Transform<Scalar,Dim>& t) const diff --git a/Eigen/src/Geometry/Scaling.h b/Eigen/src/Geometry/Scaling.h index 25d76157a..a07e118f0 100644 --- a/Eigen/src/Geometry/Scaling.h +++ b/Eigen/src/Geometry/Scaling.h @@ -29,102 +29,72 @@ * * \class Scaling * - * \brief Represents a possibly non uniform scaling transformation + * \brief Represents a generic uniform scaling transformation * * \param _Scalar the scalar type, i.e., the type of the coefficients. - * \param _Dim the dimension of the space, can be a compile time value or Dynamic * - * \note This class is not aimed to be used to store a scaling transformation, + * This class represent a uniform scaling transformation. It is the return + * type of Scaling(Scalar), and most of the time this is the only way it + * is used. In particular, this class is not aimed to be used to store a scaling transformation, * but rather to make easier the constructions and updates of Transform objects. * - * \sa class Translation, class Transform + * To represent an axis aligned scaling, use the DiagonalMatrix class. + * + * \sa Scaling(), class DiagonalMatrix, MatrixBase::asDiagonal(), class Translation, class Transform */ -template<typename _Scalar, int _Dim> -class Scaling +template<typename _Scalar> +class UniformScaling { public: - EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_Dim) - /** dimension of the space */ - enum { Dim = _Dim }; /** the scalar type of the coefficients */ typedef _Scalar Scalar; - /** corresponding vector type */ - typedef Matrix<Scalar,Dim,1> VectorType; - /** corresponding linear transformation matrix type */ - typedef Matrix<Scalar,Dim,Dim> LinearMatrixType; - /** corresponding translation type */ - typedef Translation<Scalar,Dim> TranslationType; - /** corresponding affine transformation type */ - typedef Transform<Scalar,Dim> TransformType; protected: - VectorType m_coeffs; + Scalar m_factor; public: /** Default constructor without initialization. */ - Scaling() {} + UniformScaling() {} /** Constructs and initialize a uniform scaling transformation */ - explicit inline Scaling(const Scalar& s) { m_coeffs.setConstant(s); } - /** 2D only */ - inline Scaling(const Scalar& sx, const Scalar& sy) - { - ei_assert(Dim==2); - m_coeffs.x() = sx; - m_coeffs.y() = sy; - } - /** 3D only */ - inline Scaling(const Scalar& sx, const Scalar& sy, const Scalar& sz) - { - ei_assert(Dim==3); - m_coeffs.x() = sx; - m_coeffs.y() = sy; - m_coeffs.z() = sz; - } - /** Constructs and initialize the scaling transformation from a vector of scaling coefficients */ - explicit inline Scaling(const VectorType& coeffs) : m_coeffs(coeffs) {} - - const VectorType& coeffs() const { return m_coeffs; } - VectorType& coeffs() { return m_coeffs; } - - /** Concatenates two scaling */ - inline Scaling operator* (const Scaling& other) const - { return Scaling(coeffs().cwise() * other.coeffs()); } - - /** Concatenates a scaling and a translation */ - inline TransformType operator* (const TranslationType& t) const; - - /** Concatenates a scaling and an affine transformation */ - inline TransformType operator* (const TransformType& t) const; - - /** Concatenates a scaling and a linear transformation matrix */ - // TODO returns an expression - inline LinearMatrixType operator* (const LinearMatrixType& other) const - { return coeffs().asDiagonal() * other; } + explicit inline UniformScaling(const Scalar& s) : m_factor(s) {} + + const Scalar& factor() const { return m_factor; } + Scalar& factor() { return m_factor; } + + /** Concatenates two uniform scaling */ + inline UniformScaling operator* (const UniformScaling& other) const + { return UniformScaling(m_factor * other.factor()); } - /** Concatenates a linear transformation matrix and a scaling */ + /** Concatenates a uniform scaling and a translation */ + template<int Dim> + inline Transform<Scalar,Dim> operator* (const Translation<Scalar,Dim>& t) const; + + /** Concatenates a uniform scaling and an affine transformation */ + template<int Dim> + inline Transform<Scalar,Dim> operator* (const Transform<Scalar,Dim>& t) const; + + /** Concatenates a uniform scaling and a linear transformation matrix */ // TODO returns an expression - friend inline LinearMatrixType operator* (const LinearMatrixType& other, const Scaling& s) - { return other * s.coeffs().asDiagonal(); } + template<typename Derived> + inline typename ei_eval<Derived>::type operator* (const MatrixBase<Derived>& other) const + { return other * m_factor; } + /** Concatenates a linear transformation matrix and a uniform scaling */ + // TODO returns an expression template<typename Derived> - inline LinearMatrixType operator*(const RotationBase<Derived,Dim>& r) const - { return *this * r.toRotationMatrix(); } + friend inline typename ei_eval<Derived>::type + operator* (const MatrixBase<Derived>& other, const UniformScaling& s) + { return other * s.factor(); } - /** Applies scaling to vector */ - inline VectorType operator* (const VectorType& other) const - { return coeffs().asDiagonal() * other; } + template<typename Derived,int Dim> + inline Matrix<Scalar,Dim,Dim> operator*(const RotationBase<Derived,Dim>& r) const + { return r.toRotationMatrix() * m_factor; } /** \returns the inverse scaling */ - inline Scaling inverse() const - { return Scaling(coeffs().cwise().inverse()); } - - inline Scaling& operator=(const Scaling& other) - { - m_coeffs = other.m_coeffs; - return *this; - } + inline UniformScaling inverse() const + { return UniformScaling(Scalar(1)/m_factor); } /** \returns \c *this with scalar type casted to \a NewScalarType * @@ -132,50 +102,58 @@ public: * then this function smartly returns a const reference to \c *this. */ template<typename NewScalarType> - inline typename ei_cast_return_type<Scaling,Scaling<NewScalarType,Dim> >::type cast() const - { return typename ei_cast_return_type<Scaling,Scaling<NewScalarType,Dim> >::type(*this); } + inline UniformScaling<NewScalarType> cast() const + { return UniformScaling<NewScalarType>(NewScalarType(m_factor)); } /** Copy constructor with scalar type conversion */ template<typename OtherScalarType> - inline explicit Scaling(const Scaling<OtherScalarType,Dim>& other) - { m_coeffs = other.coeffs().template cast<Scalar>(); } + inline explicit UniformScaling(const UniformScaling<OtherScalarType>& other) + { m_factor = Scalar(other.factor()); } /** \returns \c true if \c *this is approximately equal to \a other, within the precision * determined by \a prec. * * \sa MatrixBase::isApprox() */ - bool isApprox(const Scaling& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const - { return m_coeffs.isApprox(other.m_coeffs, prec); } + bool isApprox(const UniformScaling& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const + { return ei_isApprox(m_factor, other.factor(), prec); } }; +/** Constructs a uniform scaling from scale factor \a s */ +UniformScaling<float> Scaling(float s) { return UniformScaling<float>(s); } +/** Constructs a uniform scaling from scale factor \a s */ +UniformScaling<double> Scaling(double s) { return UniformScaling<double>(s); } +/** Constructs a uniform scaling from scale factor \a s */ +template<typename RealScalar> UniformScaling<std::complex<RealScalar> > +Scaling(const std::complex<RealScalar>& s) +{ return UniformScaling<std::complex<RealScalar> >(s); } + +/** Constructs a 2D axis aligned scaling */ +template<typename Scalar> DiagonalMatrix<Scalar,2> +Scaling(Scalar sx, Scalar sy) +{ return DiagonalMatrix<Scalar,2>(sx, sy); } +/** Constructs a 3D axis aligned scaling */ +template<typename Scalar> DiagonalMatrix<Scalar,3> +Scaling(Scalar sx, Scalar sy, Scalar sz) +{ return DiagonalMatrix<Scalar,3>(sx, sy, sz); } + +/** Constructs an axis aligned scaling expression from vector expression \a coeffs + * This is an alias for coeffs.asDiagonal() + */ +template<typename Derived> +const DiagonalMatrixWrapper<Derived> Scaling(const MatrixBase<Derived>& coeffs) +{ return coeffs.asDiagonal(); } + /** \addtogroup GeometryModule */ //@{ -typedef Scaling<float, 2> Scaling2f; -typedef Scaling<double,2> Scaling2d; -typedef Scaling<float, 3> Scaling3f; -typedef Scaling<double,3> Scaling3d; +/** \deprecated */ +typedef DiagonalMatrix<float, 2> AlignedScaling2f; +/** \deprecated */ +typedef DiagonalMatrix<double,2> AlignedScaling2d; +/** \deprecated */ +typedef DiagonalMatrix<float, 3> AlignedScaling3f; +/** \deprecated */ +typedef DiagonalMatrix<double,3> AlignedScaling3d; //@} -template<typename Scalar, int Dim> -inline typename Scaling<Scalar,Dim>::TransformType -Scaling<Scalar,Dim>::operator* (const TranslationType& t) const -{ - TransformType res; - res.matrix().setZero(); - res.linear().diagonal() = coeffs(); - res.translation() = m_coeffs.cwise() * t.vector(); - res(Dim,Dim) = Scalar(1); - return res; -} - -template<typename Scalar, int Dim> -inline typename Scaling<Scalar,Dim>::TransformType -Scaling<Scalar,Dim>::operator* (const TransformType& t) const -{ - TransformType res = t; - res.prescale(m_coeffs); - return res; -} - #endif // EIGEN_SCALING_H diff --git a/Eigen/src/Geometry/Transform.h b/Eigen/src/Geometry/Transform.h index 80e16a450..040988e22 100644 --- a/Eigen/src/Geometry/Transform.h +++ b/Eigen/src/Geometry/Transform.h @@ -41,7 +41,14 @@ template< typename Other, int HDim, int OtherRows=Other::RowsAtCompileTime, int OtherCols=Other::ColsAtCompileTime> -struct ei_transform_product_impl; +struct ei_transform_right_product_impl; + +template< typename Other, + int Dim, + int HDim, + int OtherRows=Other::RowsAtCompileTime, + int OtherCols=Other::ColsAtCompileTime> +struct ei_transform_left_product_impl; /** \geometry_module \ingroup GeometryModule * @@ -83,8 +90,6 @@ public: typedef Block<MatrixType,Dim,1> TranslationPart; /** corresponding translation type */ typedef Translation<Scalar,Dim> TranslationType; - /** corresponding scaling transformation type */ - typedef Scaling<Scalar,Dim> ScalingType; protected: @@ -104,7 +109,7 @@ public: } inline explicit Transform(const TranslationType& t) { *this = t; } - inline explicit Transform(const ScalingType& s) { *this = s; } + inline explicit Transform(const UniformScaling<Scalar>& s) { *this = s; } template<typename Derived> inline explicit Transform(const RotationBase<Derived, Dim>& r) { *this = r; } @@ -138,10 +143,13 @@ public: construct_from_matrix<OtherDerived, int(OtherDerived::RowsAtCompileTime) == Dim>::run(this, other); } - /** Set \c *this from a (Dim+1)^2 matrix. */ + /** Set \c *this from a Dim^2 or (Dim+1)^2 matrix. */ template<typename OtherDerived> inline Transform& operator=(const MatrixBase<OtherDerived>& other) - { m_matrix = other; return *this; } + { + construct_from_matrix<OtherDerived, int(OtherDerived::RowsAtCompileTime) == Dim>::run(this, other); + return *this; + } #ifdef EIGEN_QT_SUPPORT inline Transform(const QMatrix& other); @@ -175,24 +183,32 @@ public: inline TranslationPart translation() { return m_matrix.template block<Dim,1>(0,Dim); } /** \returns an expression of the product between the transform \c *this and a matrix expression \a other - * - * The right hand side \a other might be either: - * \li a vector of size Dim, - * \li an homogeneous vector of size Dim+1, - * \li a transformation matrix of size Dim+1 x Dim+1. - */ + * + * The right hand side \a other might be either: + * \li a vector of size Dim, + * \li an homogeneous vector of size Dim+1, + * \li a linear transformation matrix of size Dim x Dim + * \li a transformation matrix of size Dim+1 x Dim+1. + */ // note: this function is defined here because some compilers cannot find the respective declaration template<typename OtherDerived> - inline const typename ei_transform_product_impl<OtherDerived,_Dim,_Dim+1>::ResultType + inline const typename ei_transform_right_product_impl<OtherDerived,_Dim,_Dim+1>::ResultType operator * (const MatrixBase<OtherDerived> &other) const - { return ei_transform_product_impl<OtherDerived,Dim,HDim>::run(*this,other.derived()); } + { return ei_transform_right_product_impl<OtherDerived,Dim,HDim>::run(*this,other.derived()); } /** \returns the product expression of a transformation matrix \a a times a transform \a b - * The transformation matrix \a a must have a Dim+1 x Dim+1 sizes. */ - template<typename OtherDerived> - friend inline const typename ProductReturnType<OtherDerived,MatrixType>::Type + * + * The right hand side \a other might be either: + * \li a linear transformation matrix of size Dim x Dim + * \li a transformation matrix of size Dim+1 x Dim+1. + */ + template<typename OtherDerived> friend + inline const typename ei_transform_left_product_impl<OtherDerived,_Dim,_Dim+1>::ResultType operator * (const MatrixBase<OtherDerived> &a, const Transform &b) - { return a.derived() * b.matrix(); } + { return ei_transform_left_product_impl<OtherDerived,Dim,HDim>::run(a.derived(),b); } + + template<typename OtherDerived> + inline Transform& operator*=(const MatrixBase<OtherDerived>& other) { return *this = *this * other; } /** Contatenates two transformations */ inline const Transform @@ -230,16 +246,17 @@ public: 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) - { - Transform res = t; - res.matrix().row(Dim) = t.matrix().row(Dim); - res.matrix().template block<Dim,HDim>(0,0) = (mat * t.matrix().template block<Dim,HDim>(0,0)).lazy(); - return res; - } + inline Transform& operator=(const UniformScaling<Scalar>& t); + inline Transform& operator*=(const UniformScaling<Scalar>& s) { return scale(s.factor()); } + inline Transform operator*(const UniformScaling<Scalar>& s) const; + +// friend inline Transform operator*(const LinearMatrixType& mat, const Transform& t) +// { +// Transform res = t; +// res.matrix().row(Dim) = t.matrix().row(Dim); +// res.matrix().template block<Dim,HDim>(0,0) = (mat * t.matrix().template block<Dim,HDim>(0,0)).lazy(); +// return res; +// } template<typename Derived> inline Transform& operator=(const RotationBase<Derived,Dim>& r); @@ -558,19 +575,19 @@ inline Transform<Scalar,Dim> Transform<Scalar,Dim>::operator*(const TranslationT } template<typename Scalar, int Dim> -inline Transform<Scalar,Dim>& Transform<Scalar,Dim>::operator=(const ScalingType& s) +inline Transform<Scalar,Dim>& Transform<Scalar,Dim>::operator=(const UniformScaling<Scalar>& s) { m_matrix.setZero(); - linear().diagonal() = s.coeffs(); + linear().diagonal().fill(s.factor()); m_matrix.coeffRef(Dim,Dim) = Scalar(1); return *this; } template<typename Scalar, int Dim> -inline Transform<Scalar,Dim> Transform<Scalar,Dim>::operator*(const ScalingType& s) const +inline Transform<Scalar,Dim> Transform<Scalar,Dim>::operator*(const UniformScaling<Scalar>& s) const { Transform res = *this; - res.scale(s.coeffs()); + res.scale(s.factor()); return res; } @@ -722,8 +739,9 @@ Transform<Scalar,Dim>::inverse(TransformTraits traits) const *** Specializations of operator* with a MatrixBase *** *****************************************************/ +// T * affine matrix template<typename Other, int Dim, int HDim> -struct ei_transform_product_impl<Other,Dim,HDim, HDim,HDim> +struct ei_transform_right_product_impl<Other,Dim,HDim, HDim,HDim> { typedef Transform<typename Other::Scalar,Dim> TransformType; typedef typename TransformType::MatrixType MatrixType; @@ -732,8 +750,9 @@ struct ei_transform_product_impl<Other,Dim,HDim, HDim,HDim> { return tr.matrix() * other; } }; +// T * linear matrix template<typename Other, int Dim, int HDim> -struct ei_transform_product_impl<Other,Dim,HDim, Dim,Dim> +struct ei_transform_right_product_impl<Other,Dim,HDim, Dim,Dim> { typedef Transform<typename Other::Scalar,Dim> TransformType; typedef typename TransformType::MatrixType MatrixType; @@ -748,8 +767,9 @@ struct ei_transform_product_impl<Other,Dim,HDim, Dim,Dim> } }; +// T * homogeneous vector template<typename Other, int Dim, int HDim> -struct ei_transform_product_impl<Other,Dim,HDim, HDim,1> +struct ei_transform_right_product_impl<Other,Dim,HDim, HDim,1> { typedef Transform<typename Other::Scalar,Dim> TransformType; typedef typename TransformType::MatrixType MatrixType; @@ -758,8 +778,9 @@ struct ei_transform_product_impl<Other,Dim,HDim, HDim,1> { return tr.matrix() * other; } }; +// T * vector template<typename Other, int Dim, int HDim> -struct ei_transform_product_impl<Other,Dim,HDim, Dim,1> +struct ei_transform_right_product_impl<Other,Dim,HDim, Dim,1> { typedef typename Other::Scalar Scalar; typedef Transform<Scalar,Dim> TransformType; @@ -777,4 +798,31 @@ struct ei_transform_product_impl<Other,Dim,HDim, Dim,1> * (Scalar(1) / ( (tr.matrix().template block<1,Dim>(Dim,0) * other).coeff(0) + tr.matrix().coeff(Dim,Dim))); } }; +// affine matrix * T +template<typename Other, int Dim, int HDim> +struct ei_transform_left_product_impl<Other,Dim,HDim, HDim,HDim> +{ + typedef Transform<typename Other::Scalar,Dim> TransformType; + typedef typename TransformType::MatrixType MatrixType; + typedef typename ProductReturnType<MatrixType,Other>::Type ResultType; + static ResultType run(const Other& other,const TransformType& tr) + { return other * tr.matrix(); } +}; + +// linear matrix * T +template<typename Other, int Dim, int HDim> +struct ei_transform_left_product_impl<Other,Dim,HDim, Dim,Dim> +{ + typedef Transform<typename Other::Scalar,Dim> TransformType; + typedef typename TransformType::MatrixType MatrixType; + typedef TransformType ResultType; + static ResultType run(const Other& other, const TransformType& tr) + { + TransformType res; + res.matrix().row(Dim) = tr.matrix().row(Dim); + res.matrix().template corner<Dim,HDim>(TopLeft) = (other * tr.matrix().template corner<Dim,HDim>(TopLeft)).lazy(); + return res; + } +}; + #endif // EIGEN_TRANSFORM_H diff --git a/Eigen/src/Geometry/Translation.h b/Eigen/src/Geometry/Translation.h index ba8f728c3..2e90b19ce 100644 --- a/Eigen/src/Geometry/Translation.h +++ b/Eigen/src/Geometry/Translation.h @@ -52,8 +52,6 @@ public: typedef Matrix<Scalar,Dim,1> VectorType; /** corresponding linear transformation matrix type */ typedef Matrix<Scalar,Dim,Dim> LinearMatrixType; - /** corresponding scaling transformation type */ - typedef Scaling<Scalar,Dim> ScalingType; /** corresponding affine transformation type */ typedef Transform<Scalar,Dim> TransformType; @@ -80,7 +78,7 @@ public: m_coeffs.y() = sy; m_coeffs.z() = sz; } - /** Constructs and initialize the scaling transformation from a vector of scaling coefficients */ + /** Constructs and initialize the translation transformation from a vector of translation coefficients */ explicit inline Translation(const VectorType& vector) : m_coeffs(vector) {} const VectorType& vector() const { return m_coeffs; } @@ -90,24 +88,27 @@ public: inline Translation operator* (const Translation& other) const { return Translation(m_coeffs + other.m_coeffs); } - /** Concatenates a translation and a scaling */ - inline TransformType operator* (const ScalingType& other) const; + /** Concatenates a translation and a uniform scaling */ + inline TransformType operator* (const UniformScaling<Scalar>& other) const; /** Concatenates a translation and a linear transformation */ - inline TransformType operator* (const LinearMatrixType& linear) const; + template<typename OtherDerived> + inline TransformType operator* (const MatrixBase<OtherDerived>& linear) const; + /** Concatenates a translation and a rotation */ template<typename Derived> inline TransformType operator*(const RotationBase<Derived,Dim>& r) const { return *this * r.toRotationMatrix(); } - /** Concatenates a linear transformation and a translation */ + /** \returns the concatenation of a linear transformation \a l with the translation \a t */ // its a nightmare to define a templated friend function outside its declaration - friend inline TransformType operator* (const LinearMatrixType& linear, const Translation& t) + template<typename OtherDerived> friend + inline TransformType operator*(const MatrixBase<OtherDerived>& linear, const Translation& t) { TransformType res; res.matrix().setZero(); - res.linear() = linear; - res.translation() = linear * t.m_coeffs; + res.linear() = linear.derived(); + res.translation() = linear.derived() * t.m_coeffs; res.matrix().row(Dim).setZero(); res(Dim,Dim) = Scalar(1); return res; @@ -160,26 +161,26 @@ typedef Translation<float, 3> Translation3f; typedef Translation<double,3> Translation3d; //@} - template<typename Scalar, int Dim> inline typename Translation<Scalar,Dim>::TransformType -Translation<Scalar,Dim>::operator* (const ScalingType& other) const +Translation<Scalar,Dim>::operator* (const UniformScaling<Scalar>& other) const { TransformType res; res.matrix().setZero(); - res.linear().diagonal() = other.coeffs(); + res.linear().diagonal().fill(other.factor()); res.translation() = m_coeffs; res(Dim,Dim) = Scalar(1); return res; } template<typename Scalar, int Dim> +template<typename OtherDerived> inline typename Translation<Scalar,Dim>::TransformType -Translation<Scalar,Dim>::operator* (const LinearMatrixType& linear) const +Translation<Scalar,Dim>::operator* (const MatrixBase<OtherDerived>& linear) const { TransformType res; res.matrix().setZero(); - res.linear() = linear; + res.linear() = linear.derived(); res.translation() = m_coeffs; res.matrix().row(Dim).setZero(); res(Dim,Dim) = Scalar(1); |