From e5b8a59cfa5d9d7f81aad80d91c90b613efb2b67 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Sat, 25 Oct 2008 22:38:22 +0000 Subject: [PATCH] Add smart cast functions and ctor with scalar conversion (explicit) to all classes of the Geometry module. By smart I mean that if current type == new type, then it returns a const reference to *this => zero overhead --- Eigen/src/Core/util/XprHelper.h | 5 + Eigen/src/Geometry/AngleAxis.h | 21 +- Eigen/src/Geometry/Hyperplane.h | 372 ++++++++++++++------------ Eigen/src/Geometry/ParametrizedLine.h | 109 +++++--- Eigen/src/Geometry/Quaternion.h | 16 ++ Eigen/src/Geometry/Rotation2D.h | 16 ++ Eigen/src/Geometry/Scaling.h | 14 + Eigen/src/Geometry/Transform.h | 16 ++ Eigen/src/Geometry/Translation.h | 16 +- 9 files changed, 361 insertions(+), 224 deletions(-) diff --git a/Eigen/src/Core/util/XprHelper.h b/Eigen/src/Core/util/XprHelper.h index 5b8a2c021..676fb9c05 100644 --- a/Eigen/src/Core/util/XprHelper.h +++ b/Eigen/src/Core/util/XprHelper.h @@ -169,4 +169,9 @@ template stru typedef Block Type; }; +template struct ei_cast_return_type +{ + typedef typename ei_meta_if::ret,const CurrentType&,NewType>::ret type; +}; + #endif // EIGEN_XPRHELPER_H diff --git a/Eigen/src/Geometry/AngleAxis.h b/Eigen/src/Geometry/AngleAxis.h index 662ae95fb..e3759c4af 100644 --- a/Eigen/src/Geometry/AngleAxis.h +++ b/Eigen/src/Geometry/AngleAxis.h @@ -47,7 +47,7 @@ * \note This class is not aimed to be used to store a rotation transformation, * but rather to make easier the creation of other rotation (Quaternion, rotation Matrix) * and transformation objects. - * + * * \sa class Quaternion, class Transform, MatrixBase::UnitX() */ @@ -64,7 +64,7 @@ class AngleAxis : public RotationBase,3> public: using Base::operator*; - + enum { Dim = 3 }; /** the scalar type of the coefficients */ typedef _Scalar Scalar; @@ -132,6 +132,23 @@ public: template AngleAxis& fromRotationMatrix(const MatrixBase& m); Matrix3 toRotationMatrix(void) const; + + /** \returns \c *this with scalar type casted to \a NewScalarType + * + * Note that if \a NewScalarType is equal to the current scalar type of \c *this + * then this function smartly returns a const reference to \c *this. + */ + template + typename ei_cast_return_type >::type cast() const + { return typename ei_cast_return_type >::type(*this); } + + /** Copy constructor with scalar type conversion */ + template + explicit AngleAxis(const AngleAxis& other) + { + m_axis = other.axis().template cast(); + m_angle = other.angle(); + } }; /** \ingroup GeometryModule diff --git a/Eigen/src/Geometry/Hyperplane.h b/Eigen/src/Geometry/Hyperplane.h index d78b18a84..6d2462574 100644 --- a/Eigen/src/Geometry/Hyperplane.h +++ b/Eigen/src/Geometry/Hyperplane.h @@ -49,198 +49,216 @@ class Hyperplane : public ei_with_aligned_operator_new<_Scalar,_AmbientDim==Dynamic ? Dynamic : _AmbientDim+1> #endif { - public: +public: - enum { AmbientDimAtCompileTime = _AmbientDim }; - typedef _Scalar Scalar; - typedef typename NumTraits::Real RealScalar; - typedef Matrix VectorType; - typedef Matrix Coefficients; - typedef Block NormalReturnType; + enum { AmbientDimAtCompileTime = _AmbientDim }; + typedef _Scalar Scalar; + typedef typename NumTraits::Real RealScalar; + typedef Matrix VectorType; + typedef Matrix Coefficients; + typedef Block NormalReturnType; - /** Default constructor without initialization */ - inline explicit Hyperplane() {} + /** Default constructor without initialization */ + inline explicit Hyperplane() {} - /** Constructs a dynamic-size hyperplane with \a _dim the dimension - * of the ambient space */ - inline explicit Hyperplane(int _dim) : m_coeffs(_dim+1) {} + /** Constructs a dynamic-size hyperplane with \a _dim the dimension + * of the ambient space */ + inline explicit Hyperplane(int _dim) : m_coeffs(_dim+1) {} - /** Construct a plane from its normal \a n and a point \a e onto the plane. - * \warning the vector normal is assumed to be normalized. - */ - inline Hyperplane(const VectorType& n, const VectorType e) - : m_coeffs(n.size()+1) - { - normal() = n; - offset() = -e.dot(n); + /** Construct a plane from its normal \a n and a point \a e onto the plane. + * \warning the vector normal is assumed to be normalized. + */ + inline Hyperplane(const VectorType& n, const VectorType e) + : m_coeffs(n.size()+1) + { + normal() = n; + offset() = -e.dot(n); + } + + /** Constructs a plane from its normal \a n and distance to the origin \a d + * such that the algebraic equation of the plane is \f$ n \cdot x + d = 0 \f$. + * \warning the vector normal is assumed to be normalized. + */ + inline Hyperplane(const VectorType& n, Scalar d) + : m_coeffs(n.size()+1) + { + normal() = n; + offset() = d; + } + + /** Constructs a hyperplane passing through the two points. If the dimension of the ambient space + * is greater than 2, then there isn't uniqueness, so an arbitrary choice is made. + */ + static inline Hyperplane Through(const VectorType& p0, const VectorType& p1) + { + Hyperplane result(p0.size()); + result.normal() = (p1 - p0).unitOrthogonal(); + result.offset() = -result.normal().dot(p0); + return result; + } + + /** Constructs a hyperplane passing through the three points. The dimension of the ambient space + * is required to be exactly 3. + */ + static inline Hyperplane Through(const VectorType& p0, const VectorType& p1, const VectorType& p2) + { + EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(VectorType, 3); + Hyperplane result(p0.size()); + result.normal() = (p2 - p0).cross(p1 - p0).normalized(); + result.offset() = -result.normal().dot(p0); + return result; + } + + /** Constructs a hyperplane passing through the parametrized line \a parametrized. + * If the dimension of the ambient space is greater than 2, then there isn't uniqueness, + * so an arbitrary choice is made. + */ + // FIXME to be consitent with the rest this could be implemented as a static Through function ?? + explicit Hyperplane(const ParametrizedLine& parametrized) + { + normal() = parametrized.direction().unitOrthogonal(); + offset() = -normal().dot(parametrized.origin()); + } + + ~Hyperplane() {} + + /** \returns the dimension in which the plane holds */ + inline int dim() const { return AmbientDimAtCompileTime==Dynamic ? m_coeffs.size()-1 : AmbientDimAtCompileTime; } + + /** normalizes \c *this */ + void normalize(void) + { + m_coeffs /= normal().norm(); + } + + /** \returns the signed distance between the plane \c *this and a point \a p. + * \sa absDistance() + */ + inline Scalar signedDistance(const VectorType& p) const { return p.dot(normal()) + offset(); } + + /** \returns the absolute distance between the plane \c *this and a point \a p. + * \sa signedDistance() + */ + inline Scalar absDistance(const VectorType& p) const { return ei_abs(signedDistance(p)); } + + /** \returns the projection of a point \a p onto the plane \c *this. + */ + inline VectorType projection(const VectorType& p) const { return p - signedDistance(p) * normal(); } + + /** \returns a constant reference to the unit normal vector of the plane, which corresponds + * to the linear part of the implicit equation. + */ + inline const NormalReturnType normal() const { return NormalReturnType(m_coeffs,0,0,dim(),1); } + + /** \returns a non-constant reference to the unit normal vector of the plane, which corresponds + * to the linear part of the implicit equation. + */ + inline NormalReturnType normal() { return NormalReturnType(m_coeffs,0,0,dim(),1); } + + /** \returns the distance to the origin, which is also the "constant term" of the implicit equation + * \warning the vector normal is assumed to be normalized. + */ + inline const Scalar& offset() const { return m_coeffs.coeff(dim()); } + + /** \returns a non-constant reference to the distance to the origin, which is also the constant part + * of the implicit equation */ + inline Scalar& offset() { return m_coeffs(dim()); } + + /** \returns a constant reference to the coefficients c_i of the plane equation: + * \f$ c_0*x_0 + ... + c_{d-1}*x_{d-1} + c_d = 0 \f$ + */ + inline const Coefficients& coeffs() const { return m_coeffs; } + + /** \returns a non-constant reference to the coefficients c_i of the plane equation: + * \f$ c_0*x_0 + ... + c_{d-1}*x_{d-1} + c_d = 0 \f$ + */ + inline Coefficients& coeffs() { return m_coeffs; } + + /** \returns the intersection of *this with \a other. + * + * \warning The ambient space must be a plane, i.e. have dimension 2, so that \c *this and \a other are lines. + * + * \note If \a other is approximately parallel to *this, this method will return any point on *this. + */ + VectorType intersection(const Hyperplane& other) + { + EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(VectorType, 2); + Scalar det = coeffs().coeff(0) * other.coeffs().coeff(1) - coeffs().coeff(1) * other.coeffs().coeff(0); + // since the line equations ax+by=c are normalized with a^2+b^2=1, the following tests + // whether the two lines are approximately parallel. + if(ei_isMuchSmallerThan(det, Scalar(1))) + { // special case where the two lines are approximately parallel. Pick any point on the first line. + if(ei_abs(coeffs().coeff(1))>ei_abs(coeffs().coeff(0))) + return VectorType(coeffs().coeff(1), -coeffs().coeff(2)/coeffs().coeff(1)-coeffs().coeff(0)); + else + return VectorType(-coeffs().coeff(2)/coeffs().coeff(0)-coeffs().coeff(1), coeffs().coeff(0)); } - - /** Constructs a plane from its normal \a n and distance to the origin \a d - * such that the algebraic equation of the plane is \f$ n \cdot x + d = 0 \f$. - * \warning the vector normal is assumed to be normalized. - */ - inline Hyperplane(const VectorType& n, Scalar d) - : m_coeffs(n.size()+1) - { - normal() = n; - offset() = d; + else + { // general case + Scalar invdet = Scalar(1) / det; + return VectorType(invdet*(coeffs().coeff(1)*other.coeffs().coeff(2)-other.coeffs().coeff(1)*coeffs().coeff(2)), + invdet*(other.coeffs().coeff(0)*coeffs().coeff(2)-coeffs().coeff(0)*other.coeffs().coeff(2))); } + } - /** Constructs a hyperplane passing through the two points. If the dimension of the ambient space - * is greater than 2, then there isn't uniqueness, so an arbitrary choice is made. - */ - static inline Hyperplane Through(const VectorType& p0, const VectorType& p1) + /** \returns the transformation of \c *this by the transformation matrix \a mat. + * + * \param mat the Dim x Dim transformation matrix + * \param traits specifies whether the matrix \a mat represents an Isometry + * or a more generic Affine transformation. The default is Affine. + */ + template + inline Hyperplane& transform(const MatrixBase& mat, TransformTraits traits = Affine) + { + if (traits==Affine) + normal() = mat.inverse().transpose() * normal(); + else if (traits==Isometry) + normal() = mat * normal(); + else { - Hyperplane result(p0.size()); - result.normal() = (p1 - p0).unitOrthogonal(); - result.offset() = -result.normal().dot(p0); - return result; + ei_assert("invalid traits value in Hyperplane::transform()"); } + return *this; + } - /** Constructs a hyperplane passing through the three points. The dimension of the ambient space - * is required to be exactly 3. - */ - static inline Hyperplane Through(const VectorType& p0, const VectorType& p1, const VectorType& p2) - { - EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(VectorType, 3); - Hyperplane result(p0.size()); - result.normal() = (p2 - p0).cross(p1 - p0).normalized(); - result.offset() = -result.normal().dot(p0); - return result; - } + /** \returns the transformation of \c *this by the transformation \a t + * + * \param t the transformation of dimension Dim + * \param traits specifies whether the transformation \a t represents an Isometry + * or a more generic Affine transformation. The default is Affine. + * Other kind of transformations are not supported. + */ + inline Hyperplane& transform(const Transform& t, + TransformTraits traits = Affine) + { + transform(t.linear(), traits); + offset() -= t.translation().dot(normal()); + return *this; + } - /** Constructs a hyperplane passing through the parametrized line \a parametrized. - * If the dimension of the ambient space is greater than 2, then there isn't uniqueness, - * so an arbitrary choice is made. - */ - // FIXME to be consitent with the rest this could be implemented as a static Through function ?? - explicit Hyperplane(const ParametrizedLine& parametrized) - { - normal() = parametrized.direction().unitOrthogonal(); - offset() = -normal().dot(parametrized.origin()); - } + /** \returns \c *this with scalar type casted to \a NewScalarType + * + * Note that if \a NewScalarType is equal to the current scalar type of \c *this + * then this function smartly returns a const reference to \c *this. + */ + template + typename ei_cast_return_type >::type cast() const + { + return typename ei_cast_return_type >::type(*this); + } - ~Hyperplane() {} - - /** \returns the dimension in which the plane holds */ - inline int dim() const { return AmbientDimAtCompileTime==Dynamic ? m_coeffs.size()-1 : AmbientDimAtCompileTime; } - - /** normalizes \c *this */ - void normalize(void) - { - m_coeffs /= normal().norm(); - } - - /** \returns the signed distance between the plane \c *this and a point \a p. - * \sa absDistance() - */ - inline Scalar signedDistance(const VectorType& p) const { return p.dot(normal()) + offset(); } - - /** \returns the absolute distance between the plane \c *this and a point \a p. - * \sa signedDistance() - */ - inline Scalar absDistance(const VectorType& p) const { return ei_abs(signedDistance(p)); } - - /** \returns the projection of a point \a p onto the plane \c *this. - */ - inline VectorType projection(const VectorType& p) const { return p - signedDistance(p) * normal(); } - - /** \returns a constant reference to the unit normal vector of the plane, which corresponds - * to the linear part of the implicit equation. - */ - inline const NormalReturnType normal() const { return NormalReturnType(m_coeffs,0,0,dim(),1); } - - /** \returns a non-constant reference to the unit normal vector of the plane, which corresponds - * to the linear part of the implicit equation. - */ - inline NormalReturnType normal() { return NormalReturnType(m_coeffs,0,0,dim(),1); } - - /** \returns the distance to the origin, which is also the "constant term" of the implicit equation - * \warning the vector normal is assumed to be normalized. - */ - inline const Scalar& offset() const { return m_coeffs.coeff(dim()); } - - /** \returns a non-constant reference to the distance to the origin, which is also the constant part - * of the implicit equation */ - inline Scalar& offset() { return m_coeffs(dim()); } - - /** \returns a constant reference to the coefficients c_i of the plane equation: - * \f$ c_0*x_0 + ... + c_{d-1}*x_{d-1} + c_d = 0 \f$ - */ - inline const Coefficients& coeffs() const { return m_coeffs; } - - /** \returns a non-constant reference to the coefficients c_i of the plane equation: - * \f$ c_0*x_0 + ... + c_{d-1}*x_{d-1} + c_d = 0 \f$ - */ - inline Coefficients& coeffs() { return m_coeffs; } - - /** \returns the intersection of *this with \a other. - * - * \warning The ambient space must be a plane, i.e. have dimension 2, so that \c *this and \a other are lines. - * - * \note If \a other is approximately parallel to *this, this method will return any point on *this. - */ - VectorType intersection(const Hyperplane& other) - { - EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(VectorType, 2); - Scalar det = coeffs().coeff(0) * other.coeffs().coeff(1) - coeffs().coeff(1) * other.coeffs().coeff(0); - // since the line equations ax+by=c are normalized with a^2+b^2=1, the following tests - // whether the two lines are approximately parallel. - if(ei_isMuchSmallerThan(det, Scalar(1))) - { // special case where the two lines are approximately parallel. Pick any point on the first line. - if(ei_abs(coeffs().coeff(1))>ei_abs(coeffs().coeff(0))) - return VectorType(coeffs().coeff(1), -coeffs().coeff(2)/coeffs().coeff(1)-coeffs().coeff(0)); - else - return VectorType(-coeffs().coeff(2)/coeffs().coeff(0)-coeffs().coeff(1), coeffs().coeff(0)); - } - else - { // general case - Scalar invdet = Scalar(1) / det; - return VectorType(invdet*(coeffs().coeff(1)*other.coeffs().coeff(2)-other.coeffs().coeff(1)*coeffs().coeff(2)), - invdet*(other.coeffs().coeff(0)*coeffs().coeff(2)-coeffs().coeff(0)*other.coeffs().coeff(2))); - } - } - - /** \returns the transformation of \c *this by the transformation matrix \a mat. - * - * \param mat the Dim x Dim transformation matrix - * \param traits specifies whether the matrix \a mat represents an Isometry - * or a more generic Affine transformation. The default is Affine. - */ - template - inline Hyperplane& transform(const MatrixBase& mat, TransformTraits traits = Affine) - { - if (traits==Affine) - normal() = mat.inverse().transpose() * normal(); - else if (traits==Isometry) - normal() = mat * normal(); - else - { - ei_assert("invalid traits value in Hyperplane::transform()"); - } - return *this; - } - - /** \returns the transformation of \c *this by the transformation \a t - * - * \param t the transformation of dimension Dim - * \param traits specifies whether the transformation \a t represents an Isometry - * or a more generic Affine transformation. The default is Affine. - * Other kind of transformations are not supported. - */ - inline Hyperplane& transform(const Transform& t, - TransformTraits traits = Affine) - { - transform(t.linear(), traits); - offset() -= t.translation().dot(normal()); - return *this; - } + /** Copy constructor with scalar type conversion */ + template + explicit Hyperplane(const Hyperplane& other) + { m_coeffs = other.coeffs().template cast(); } protected: - Coefficients m_coeffs; + Coefficients m_coeffs; }; #endif // EIGEN_HYPERPLANE_H diff --git a/Eigen/src/Geometry/ParametrizedLine.h b/Eigen/src/Geometry/ParametrizedLine.h index 9fcb5b36c..8a1d79252 100644 --- a/Eigen/src/Geometry/ParametrizedLine.h +++ b/Eigen/src/Geometry/ParametrizedLine.h @@ -45,65 +45,86 @@ class ParametrizedLine : public ei_with_aligned_operator_new<_Scalar,_AmbientDim> #endif { - public: +public: - enum { AmbientDimAtCompileTime = _AmbientDim }; - typedef _Scalar Scalar; - typedef typename NumTraits::Real RealScalar; - typedef Matrix VectorType; + enum { AmbientDimAtCompileTime = _AmbientDim }; + typedef _Scalar Scalar; + typedef typename NumTraits::Real RealScalar; + typedef Matrix VectorType; - /** Default constructor without initialization */ - inline explicit ParametrizedLine() {} + /** Default constructor without initialization */ + inline explicit ParametrizedLine() {} - /** Constructs a dynamic-size line with \a _dim the dimension - * of the ambient space */ - inline explicit ParametrizedLine(int _dim) : m_origin(_dim), m_direction(_dim) {} + /** Constructs a dynamic-size line with \a _dim the dimension + * of the ambient space */ + inline explicit ParametrizedLine(int _dim) : m_origin(_dim), m_direction(_dim) {} - /** Initializes a parametrized line of direction \a direction and origin \a origin. - * \warning the vector direction is assumed to be normalized. - */ - ParametrizedLine(const VectorType& origin, const VectorType& direction) - : m_origin(origin), m_direction(direction) {} + /** Initializes a parametrized line of direction \a direction and origin \a origin. + * \warning the vector direction is assumed to be normalized. + */ + ParametrizedLine(const VectorType& origin, const VectorType& direction) + : m_origin(origin), m_direction(direction) {} - explicit ParametrizedLine(const Hyperplane<_Scalar, _AmbientDim>& hyperplane); + explicit ParametrizedLine(const Hyperplane<_Scalar, _AmbientDim>& hyperplane); - /** Constructs a parametrized line going from \a p0 to \a p1. */ - static inline ParametrizedLine Through(const VectorType& p0, const VectorType& p1) - { return ParametrizedLine(p0, (p1-p0).normalized()); } + /** Constructs a parametrized line going from \a p0 to \a p1. */ + static inline ParametrizedLine Through(const VectorType& p0, const VectorType& p1) + { return ParametrizedLine(p0, (p1-p0).normalized()); } - ~ParametrizedLine() {} + ~ParametrizedLine() {} - /** \returns the dimension in which the line holds */ - inline int dim() const { return m_direction.size(); } + /** \returns the dimension in which the line holds */ + inline int dim() const { return m_direction.size(); } - const VectorType& origin() const { return m_origin; } - VectorType& origin() { return m_origin; } + const VectorType& origin() const { return m_origin; } + VectorType& origin() { return m_origin; } - const VectorType& direction() const { return m_direction; } - VectorType& direction() { return m_direction; } + const VectorType& direction() const { return m_direction; } + VectorType& direction() { return m_direction; } - /** \returns the squared distance of a point \a p to its projection onto the line \c *this. - * \sa distance() - */ - RealScalar squaredDistance(const VectorType& p) const - { - VectorType diff = p-origin(); - return (diff - diff.dot(direction())* direction()).norm2(); - } - /** \returns the distance of a point \a p to its projection onto the line \c *this. - * \sa squaredDistance() - */ - RealScalar distance(const VectorType& p) const { return ei_sqrt(squaredDistance(p)); } + /** \returns the squared distance of a point \a p to its projection onto the line \c *this. + * \sa distance() + */ + RealScalar squaredDistance(const VectorType& p) const + { + VectorType diff = p-origin(); + return (diff - diff.dot(direction())* direction()).norm2(); + } + /** \returns the distance of a point \a p to its projection onto the line \c *this. + * \sa squaredDistance() + */ + RealScalar distance(const VectorType& p) const { return ei_sqrt(squaredDistance(p)); } - /** \returns the projection of a point \a p onto the line \c *this. */ - VectorType projection(const VectorType& p) const - { return origin() + (p-origin()).dot(direction()) * direction(); } + /** \returns the projection of a point \a p onto the line \c *this. */ + VectorType projection(const VectorType& p) const + { return origin() + (p-origin()).dot(direction()) * direction(); } - Scalar intersection(const Hyperplane<_Scalar, _AmbientDim>& hyperplane); + Scalar intersection(const Hyperplane<_Scalar, _AmbientDim>& hyperplane); - protected: + /** \returns \c *this with scalar type casted to \a NewScalarType + * + * Note that if \a NewScalarType is equal to the current scalar type of \c *this + * then this function smartly returns a const reference to \c *this. + */ + template + typename ei_cast_return_type >::type cast() const + { + return typename ei_cast_return_type >::type(*this); + } - VectorType m_origin, m_direction; + /** Copy constructor with scalar type conversion */ + template + explicit ParametrizedLine(const ParametrizedLine& other) + { + m_origin = other.origin().template cast(); + m_direction = other.direction().template cast(); + } + +protected: + + VectorType m_origin, m_direction; }; /** Constructs a parametrized line from a 2D hyperplane diff --git a/Eigen/src/Geometry/Quaternion.h b/Eigen/src/Geometry/Quaternion.h index 9403181ca..820d30568 100644 --- a/Eigen/src/Geometry/Quaternion.h +++ b/Eigen/src/Geometry/Quaternion.h @@ -195,6 +195,22 @@ public: template Vector3 operator* (const MatrixBase& vec) const; + /** \returns \c *this with scalar type casted to \a NewScalarType + * + * Note that if \a NewScalarType is equal to the current scalar type of \c *this + * then this function smartly returns a const reference to \c *this. + */ + template + typename ei_cast_return_type >::type cast() const + { return typename ei_cast_return_type >::type(*this); } + + /** Copy constructor with scalar type conversion */ + template + explicit Quaternion(const Quaternion& other) + { + m_coeffs = other.coeffs().template cast(); + } + }; /** \ingroup GeometryModule diff --git a/Eigen/src/Geometry/Rotation2D.h b/Eigen/src/Geometry/Rotation2D.h index c0bda5f69..8e8396713 100644 --- a/Eigen/src/Geometry/Rotation2D.h +++ b/Eigen/src/Geometry/Rotation2D.h @@ -100,6 +100,22 @@ public: */ inline Rotation2D slerp(Scalar t, const Rotation2D& other) const { return m_angle * (1-t) + other.angle() * t; } + + /** \returns \c *this with scalar type casted to \a NewScalarType + * + * Note that if \a NewScalarType is equal to the current scalar type of \c *this + * then this function smartly returns a const reference to \c *this. + */ + template + typename ei_cast_return_type >::type cast() const + { return typename ei_cast_return_type >::type(*this); } + + /** Copy constructor with scalar type conversion */ + template + explicit Rotation2D(const Rotation2D& other) + { + m_angle = other.angle(); + } }; /** \ingroup GeometryModule diff --git a/Eigen/src/Geometry/Scaling.h b/Eigen/src/Geometry/Scaling.h index da7cca68e..dd40d2ed3 100644 --- a/Eigen/src/Geometry/Scaling.h +++ b/Eigen/src/Geometry/Scaling.h @@ -128,6 +128,20 @@ public: return *this; } + /** \returns \c *this with scalar type casted to \a NewScalarType + * + * Note that if \a NewScalarType is equal to the current scalar type of \c *this + * then this function smartly returns a const reference to \c *this. + */ + template + typename ei_cast_return_type >::type cast() const + { return typename ei_cast_return_type >::type(*this); } + + /** Copy constructor with scalar type conversion */ + template + explicit Scaling(const Scaling& other) + { m_coeffs = other.coeffs().template cast(); } + }; /** \addtogroup GeometryModule */ diff --git a/Eigen/src/Geometry/Transform.h b/Eigen/src/Geometry/Transform.h index ee7bdce83..003f5d755 100644 --- a/Eigen/src/Geometry/Transform.h +++ b/Eigen/src/Geometry/Transform.h @@ -241,9 +241,25 @@ public: inline const MatrixType inverse(TransformTraits traits = Affine) const; + /** \returns a const pointer to the column major internal matrix */ const Scalar* data() const { return m_matrix.data(); } + /** \returns a non-const pointer to the column major internal matrix */ Scalar* data() { return m_matrix.data(); } + /** \returns \c *this with scalar type casted to \a NewScalarType + * + * Note that if \a NewScalarType is equal to the current scalar type of \c *this + * then this function smartly returns a const reference to \c *this. + */ + template + typename ei_cast_return_type >::type cast() const + { return typename ei_cast_return_type >::type(*this); } + + /** Copy constructor with scalar type conversion */ + template + explicit Transform(const Transform& other) + { m_matrix = other.matrix().template cast(); } + protected: }; diff --git a/Eigen/src/Geometry/Translation.h b/Eigen/src/Geometry/Translation.h index a322205a4..5d01c3044 100644 --- a/Eigen/src/Geometry/Translation.h +++ b/Eigen/src/Geometry/Translation.h @@ -91,7 +91,7 @@ public: /** Concatenates two translation */ 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; @@ -131,6 +131,20 @@ public: return *this; } + /** \returns \c *this with scalar type casted to \a NewScalarType + * + * Note that if \a NewScalarType is equal to the current scalar type of \c *this + * then this function smartly returns a const reference to \c *this. + */ + template + typename ei_cast_return_type >::type cast() const + { return typename ei_cast_return_type >::type(*this); } + + /** Copy constructor with scalar type conversion */ + template + explicit Translation(const Translation& other) + { m_coeffs = other.vector().template cast(); } + }; /** \addtogroup GeometryModule */