diff options
author | Gael Guennebaud <g.gael@free.fr> | 2008-10-25 22:38:22 +0000 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2008-10-25 22:38:22 +0000 |
commit | e5b8a59cfa5d9d7f81aad80d91c90b613efb2b67 (patch) | |
tree | b1d2d0d0c4b0a74e93e2feb2cbe34e711ff48599 /Eigen | |
parent | 568a7e8eba0cac0555c286aa44a594c109b73276 (diff) |
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
Diffstat (limited to 'Eigen')
-rw-r--r-- | Eigen/src/Core/util/XprHelper.h | 5 | ||||
-rw-r--r-- | Eigen/src/Geometry/AngleAxis.h | 21 | ||||
-rw-r--r-- | Eigen/src/Geometry/Hyperplane.h | 370 | ||||
-rw-r--r-- | Eigen/src/Geometry/ParametrizedLine.h | 139 | ||||
-rw-r--r-- | Eigen/src/Geometry/Quaternion.h | 16 | ||||
-rw-r--r-- | Eigen/src/Geometry/Rotation2D.h | 16 | ||||
-rw-r--r-- | Eigen/src/Geometry/Scaling.h | 14 | ||||
-rw-r--r-- | Eigen/src/Geometry/Transform.h | 16 | ||||
-rw-r--r-- | Eigen/src/Geometry/Translation.h | 16 |
9 files changed, 375 insertions, 238 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<typename ExpressionType, int RowsOrSize=Dynamic, int Cols=Dynamic> stru typedef Block<ExpressionType, RowsOrSize, Cols> Type; }; +template<typename CurrentType, typename NewType> struct ei_cast_return_type +{ + typedef typename ei_meta_if<ei_is_same_type<CurrentType,NewType>::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<AngleAxis<_Scalar>,3> public: using Base::operator*; - + enum { Dim = 3 }; /** the scalar type of the coefficients */ typedef _Scalar Scalar; @@ -132,6 +132,23 @@ public: template<typename Derived> AngleAxis& fromRotationMatrix(const MatrixBase<Derived>& 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 NewScalarType> + typename ei_cast_return_type<AngleAxis,AngleAxis<NewScalarType> >::type cast() const + { return typename ei_cast_return_type<AngleAxis,AngleAxis<NewScalarType> >::type(*this); } + + /** Copy constructor with scalar type conversion */ + template<typename OtherScalarType> + explicit AngleAxis(const AngleAxis<OtherScalarType>& other) + { + m_axis = other.axis().template cast<OtherScalarType>(); + 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: - - enum { AmbientDimAtCompileTime = _AmbientDim }; - typedef _Scalar Scalar; - typedef typename NumTraits<Scalar>::Real RealScalar; - typedef Matrix<Scalar,AmbientDimAtCompileTime,1> VectorType; - typedef Matrix<Scalar,AmbientDimAtCompileTime==Dynamic - ? Dynamic - : AmbientDimAtCompileTime+1,1> Coefficients; - typedef Block<Coefficients,AmbientDimAtCompileTime,1> NormalReturnType; - - /** 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) {} - - /** 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); - } +public: - /** 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; - } + enum { AmbientDimAtCompileTime = _AmbientDim }; + typedef _Scalar Scalar; + typedef typename NumTraits<Scalar>::Real RealScalar; + typedef Matrix<Scalar,AmbientDimAtCompileTime,1> VectorType; + typedef Matrix<Scalar,AmbientDimAtCompileTime==Dynamic + ? Dynamic + : AmbientDimAtCompileTime+1,1> Coefficients; + typedef Block<Coefficients,AmbientDimAtCompileTime,1> NormalReturnType; - /** 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; - } + /** Default constructor without initialization */ + inline explicit Hyperplane() {} - /** 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 dynamic-size hyperplane with \a _dim the dimension + * of the ambient space */ + inline explicit Hyperplane(int _dim) : m_coeffs(_dim+1) {} - /** 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<Scalar, AmbientDimAtCompileTime>& parametrized) - { - normal() = parametrized.direction().unitOrthogonal(); - offset() = -normal().dot(parametrized.origin()); - } + /** 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); + } - ~Hyperplane() {} + /** 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; + } - /** \returns the dimension in which the plane holds */ - inline int dim() const { return AmbientDimAtCompileTime==Dynamic ? m_coeffs.size()-1 : AmbientDimAtCompileTime; } + /** 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; + } - /** normalizes \c *this */ - void normalize(void) - { - m_coeffs /= normal().norm(); - } + /** 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 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))); - } - } + /** 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<Scalar, AmbientDimAtCompileTime>& parametrized) + { + normal() = parametrized.direction().unitOrthogonal(); + offset() = -normal().dot(parametrized.origin()); + } - /** \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<typename XprType> - inline Hyperplane& transform(const MatrixBase<XprType>& 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; + ~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 \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<Scalar,AmbientDimAtCompileTime>& t, - TransformTraits traits = Affine) + /** \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<typename XprType> + inline Hyperplane& transform(const MatrixBase<XprType>& mat, TransformTraits traits = Affine) + { + if (traits==Affine) + normal() = mat.inverse().transpose() * normal(); + else if (traits==Isometry) + normal() = mat * normal(); + else { - transform(t.linear(), traits); - offset() -= t.translation().dot(normal()); - return *this; + 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<Scalar,AmbientDimAtCompileTime>& t, + TransformTraits traits = Affine) + { + transform(t.linear(), traits); + offset() -= t.translation().dot(normal()); + 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 NewScalarType> + typename ei_cast_return_type<Hyperplane, + Hyperplane<NewScalarType,AmbientDimAtCompileTime> >::type cast() const + { + return typename ei_cast_return_type<Hyperplane, + Hyperplane<NewScalarType,AmbientDimAtCompileTime> >::type(*this); + } + + /** Copy constructor with scalar type conversion */ + template<typename OtherScalarType> + explicit Hyperplane(const Hyperplane<OtherScalarType,AmbientDimAtCompileTime>& other) + { m_coeffs = other.coeffs().template cast<OtherScalarType>(); } 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: - - enum { AmbientDimAtCompileTime = _AmbientDim }; - typedef _Scalar Scalar; - typedef typename NumTraits<Scalar>::Real RealScalar; - typedef Matrix<Scalar,AmbientDimAtCompileTime,1> VectorType; - - /** 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) {} - - /** 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); - - /** 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() {} - - /** \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& 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 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); - - protected: - - VectorType m_origin, m_direction; +public: + + enum { AmbientDimAtCompileTime = _AmbientDim }; + typedef _Scalar Scalar; + typedef typename NumTraits<Scalar>::Real RealScalar; + typedef Matrix<Scalar,AmbientDimAtCompileTime,1> VectorType; + + /** 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) {} + + /** 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); + + /** 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() {} + + /** \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& 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 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); + + /** \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 NewScalarType> + typename ei_cast_return_type<ParametrizedLine, + ParametrizedLine<NewScalarType,AmbientDimAtCompileTime> >::type cast() const + { + return typename ei_cast_return_type<ParametrizedLine, + ParametrizedLine<NewScalarType,AmbientDimAtCompileTime> >::type(*this); + } + + /** Copy constructor with scalar type conversion */ + template<typename OtherScalarType> + explicit ParametrizedLine(const ParametrizedLine<OtherScalarType,AmbientDimAtCompileTime>& other) + { + m_origin = other.origin().template cast<OtherScalarType>(); + m_direction = other.direction().template cast<OtherScalarType>(); + } + +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<typename Derived> Vector3 operator* (const MatrixBase<Derived>& 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 NewScalarType> + typename ei_cast_return_type<Quaternion,Quaternion<NewScalarType> >::type cast() const + { return typename ei_cast_return_type<Quaternion,Quaternion<NewScalarType> >::type(*this); } + + /** Copy constructor with scalar type conversion */ + template<typename OtherScalarType> + explicit Quaternion(const Quaternion<OtherScalarType>& other) + { + m_coeffs = other.coeffs().template cast<OtherScalarType>(); + } + }; /** \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 NewScalarType> + typename ei_cast_return_type<Rotation2D,Rotation2D<NewScalarType> >::type cast() const + { return typename ei_cast_return_type<Rotation2D,Rotation2D<NewScalarType> >::type(*this); } + + /** Copy constructor with scalar type conversion */ + template<typename OtherScalarType> + explicit Rotation2D(const Rotation2D<OtherScalarType>& 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 NewScalarType> + typename ei_cast_return_type<Scaling,Scaling<NewScalarType,Dim> >::type cast() const + { return typename ei_cast_return_type<Scaling,Scaling<NewScalarType,Dim> >::type(*this); } + + /** Copy constructor with scalar type conversion */ + template<typename OtherScalarType> + explicit Scaling(const Scaling<OtherScalarType,Dim>& other) + { m_coeffs = other.coeffs().template cast<OtherScalarType>(); } + }; /** \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 NewScalarType> + typename ei_cast_return_type<Transform,Transform<NewScalarType,Dim> >::type cast() const + { return typename ei_cast_return_type<Transform,Transform<NewScalarType,Dim> >::type(*this); } + + /** Copy constructor with scalar type conversion */ + template<typename OtherScalarType> + explicit Transform(const Transform<OtherScalarType,Dim>& other) + { m_matrix = other.matrix().template cast<OtherScalarType>(); } + 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 NewScalarType> + typename ei_cast_return_type<Translation,Translation<NewScalarType,Dim> >::type cast() const + { return typename ei_cast_return_type<Translation,Translation<NewScalarType,Dim> >::type(*this); } + + /** Copy constructor with scalar type conversion */ + template<typename OtherScalarType> + explicit Translation(const Translation<OtherScalarType,Dim>& other) + { m_coeffs = other.vector().template cast<OtherScalarType>(); } + }; /** \addtogroup GeometryModule */ |