|  | // This file is part of Eigen, a lightweight C++ template library | 
|  | // for linear algebra. | 
|  | // | 
|  | // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> | 
|  | // Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com> | 
|  | // | 
|  | // This Source Code Form is subject to the terms of the Mozilla | 
|  | // Public License v. 2.0. If a copy of the MPL was not distributed | 
|  | // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | 
|  |  | 
|  | #ifndef EIGEN_PARAMETRIZEDLINE_H | 
|  | #define EIGEN_PARAMETRIZEDLINE_H | 
|  |  | 
|  | // IWYU pragma: private | 
|  | #include "./InternalHeaderCheck.h" | 
|  |  | 
|  | namespace Eigen { | 
|  |  | 
|  | /** \geometry_module \ingroup Geometry_Module | 
|  | * | 
|  | * \class ParametrizedLine | 
|  | * | 
|  | * \brief A parametrized line | 
|  | * | 
|  | * A parametrized line is defined by an origin point \f$ \mathbf{o} \f$ and a unit | 
|  | * direction vector \f$ \mathbf{d} \f$ such that the line corresponds to | 
|  | * the set \f$ l(t) = \mathbf{o} + t \mathbf{d} \f$, \f$ t \in \mathbf{R} \f$. | 
|  | * | 
|  | * \tparam Scalar_ the scalar type, i.e., the type of the coefficients | 
|  | * \tparam AmbientDim_ the dimension of the ambient space, can be a compile time value or Dynamic. | 
|  | */ | 
|  | template <typename Scalar_, int AmbientDim_, int Options_> | 
|  | class ParametrizedLine { | 
|  | public: | 
|  | EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(Scalar_, AmbientDim_) | 
|  | enum { AmbientDimAtCompileTime = AmbientDim_, Options = Options_ }; | 
|  | typedef Scalar_ Scalar; | 
|  | typedef typename NumTraits<Scalar>::Real RealScalar; | 
|  | typedef Eigen::Index Index;  ///< \deprecated since Eigen 3.3 | 
|  | typedef Matrix<Scalar, AmbientDimAtCompileTime, 1, Options> VectorType; | 
|  |  | 
|  | /** Default constructor without initialization */ | 
|  | EIGEN_DEVICE_FUNC inline ParametrizedLine() {} | 
|  |  | 
|  | template <int OtherOptions> | 
|  | EIGEN_DEVICE_FUNC ParametrizedLine(const ParametrizedLine<Scalar, AmbientDimAtCompileTime, OtherOptions>& other) | 
|  | : m_origin(other.origin()), m_direction(other.direction()) {} | 
|  |  | 
|  | /** Constructs a dynamic-size line with \a _dim the dimension | 
|  | * of the ambient space */ | 
|  | EIGEN_DEVICE_FUNC inline explicit ParametrizedLine(Index _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. | 
|  | */ | 
|  | EIGEN_DEVICE_FUNC ParametrizedLine(const VectorType& origin, const VectorType& direction) | 
|  | : m_origin(origin), m_direction(direction) {} | 
|  |  | 
|  | template <int OtherOptions> | 
|  | EIGEN_DEVICE_FUNC explicit ParametrizedLine(const Hyperplane<Scalar_, AmbientDim_, OtherOptions>& hyperplane); | 
|  |  | 
|  | /** Constructs a parametrized line going from \a p0 to \a p1. */ | 
|  | EIGEN_DEVICE_FUNC static inline ParametrizedLine Through(const VectorType& p0, const VectorType& p1) { | 
|  | return ParametrizedLine(p0, (p1 - p0).normalized()); | 
|  | } | 
|  |  | 
|  | EIGEN_DEVICE_FUNC ~ParametrizedLine() {} | 
|  |  | 
|  | /** \returns the dimension in which the line holds */ | 
|  | EIGEN_DEVICE_FUNC inline Index dim() const { return m_direction.size(); } | 
|  |  | 
|  | EIGEN_DEVICE_FUNC const VectorType& origin() const { return m_origin; } | 
|  | EIGEN_DEVICE_FUNC VectorType& origin() { return m_origin; } | 
|  |  | 
|  | EIGEN_DEVICE_FUNC const VectorType& direction() const { return m_direction; } | 
|  | EIGEN_DEVICE_FUNC VectorType& direction() { return m_direction; } | 
|  |  | 
|  | /** \returns the squared distance of a point \a p to its projection onto the line \c *this. | 
|  | * \sa distance() | 
|  | */ | 
|  | EIGEN_DEVICE_FUNC RealScalar squaredDistance(const VectorType& p) const { | 
|  | VectorType diff = p - origin(); | 
|  | return (diff - direction().dot(diff) * direction()).squaredNorm(); | 
|  | } | 
|  | /** \returns the distance of a point \a p to its projection onto the line \c *this. | 
|  | * \sa squaredDistance() | 
|  | */ | 
|  | EIGEN_DEVICE_FUNC RealScalar distance(const VectorType& p) const { | 
|  | EIGEN_USING_STD(sqrt) return sqrt(squaredDistance(p)); | 
|  | } | 
|  |  | 
|  | /** \returns the projection of a point \a p onto the line \c *this. */ | 
|  | EIGEN_DEVICE_FUNC VectorType projection(const VectorType& p) const { | 
|  | return origin() + direction().dot(p - origin()) * direction(); | 
|  | } | 
|  |  | 
|  | EIGEN_DEVICE_FUNC VectorType pointAt(const Scalar& t) const; | 
|  |  | 
|  | template <int OtherOptions> | 
|  | EIGEN_DEVICE_FUNC Scalar | 
|  | intersectionParameter(const Hyperplane<Scalar_, AmbientDim_, OtherOptions>& hyperplane) const; | 
|  |  | 
|  | template <int OtherOptions> | 
|  | EIGEN_DEVICE_FUNC Scalar intersection(const Hyperplane<Scalar_, AmbientDim_, OtherOptions>& hyperplane) const; | 
|  |  | 
|  | template <int OtherOptions> | 
|  | EIGEN_DEVICE_FUNC VectorType | 
|  | intersectionPoint(const Hyperplane<Scalar_, AmbientDim_, OtherOptions>& hyperplane) const; | 
|  |  | 
|  | /** Applies the transformation matrix \a mat to \c *this and returns a reference to \c *this. | 
|  | * | 
|  | * \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> | 
|  | EIGEN_DEVICE_FUNC inline ParametrizedLine& transform(const MatrixBase<XprType>& mat, | 
|  | TransformTraits traits = Affine) { | 
|  | if (traits == Affine) | 
|  | direction() = (mat * direction()).normalized(); | 
|  | else if (traits == Isometry) | 
|  | direction() = mat * direction(); | 
|  | else { | 
|  | eigen_assert(0 && "invalid traits value in ParametrizedLine::transform()"); | 
|  | } | 
|  | origin() = mat * origin(); | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | /** Applies the transformation \a t to \c *this and returns a reference to \c *this. | 
|  | * | 
|  | * \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. | 
|  | */ | 
|  | template <int TrOptions> | 
|  | EIGEN_DEVICE_FUNC inline ParametrizedLine& transform( | 
|  | const Transform<Scalar, AmbientDimAtCompileTime, Affine, TrOptions>& t, TransformTraits traits = Affine) { | 
|  | transform(t.linear(), traits); | 
|  | origin() += t.translation(); | 
|  | 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> | 
|  | EIGEN_DEVICE_FUNC inline | 
|  | typename internal::cast_return_type<ParametrizedLine, | 
|  | ParametrizedLine<NewScalarType, AmbientDimAtCompileTime, Options> >::type | 
|  | cast() const { | 
|  | return typename internal::cast_return_type< | 
|  | ParametrizedLine, ParametrizedLine<NewScalarType, AmbientDimAtCompileTime, Options> >::type(*this); | 
|  | } | 
|  |  | 
|  | /** Copy constructor with scalar type conversion */ | 
|  | template <typename OtherScalarType, int OtherOptions> | 
|  | EIGEN_DEVICE_FUNC inline explicit ParametrizedLine( | 
|  | const ParametrizedLine<OtherScalarType, AmbientDimAtCompileTime, OtherOptions>& other) { | 
|  | m_origin = other.origin().template cast<Scalar>(); | 
|  | m_direction = other.direction().template cast<Scalar>(); | 
|  | } | 
|  |  | 
|  | /** \returns \c true if \c *this is approximately equal to \a other, within the precision | 
|  | * determined by \a prec. | 
|  | * | 
|  | * \sa MatrixBase::isApprox() */ | 
|  | EIGEN_DEVICE_FUNC bool isApprox(const ParametrizedLine& other, const typename NumTraits<Scalar>::Real& prec = | 
|  | NumTraits<Scalar>::dummy_precision()) const { | 
|  | return m_origin.isApprox(other.m_origin, prec) && m_direction.isApprox(other.m_direction, prec); | 
|  | } | 
|  |  | 
|  | protected: | 
|  | VectorType m_origin, m_direction; | 
|  | }; | 
|  |  | 
|  | /** Constructs a parametrized line from a 2D hyperplane | 
|  | * | 
|  | * \warning the ambient space must have dimension 2 such that the hyperplane actually describes a line | 
|  | */ | 
|  | template <typename Scalar_, int AmbientDim_, int Options_> | 
|  | template <int OtherOptions> | 
|  | EIGEN_DEVICE_FUNC inline ParametrizedLine<Scalar_, AmbientDim_, Options_>::ParametrizedLine( | 
|  | const Hyperplane<Scalar_, AmbientDim_, OtherOptions>& hyperplane) { | 
|  | EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(VectorType, 2) | 
|  | direction() = hyperplane.normal().unitOrthogonal(); | 
|  | origin() = -hyperplane.normal() * hyperplane.offset(); | 
|  | } | 
|  |  | 
|  | /** \returns the point at \a t along this line | 
|  | */ | 
|  | template <typename Scalar_, int AmbientDim_, int Options_> | 
|  | EIGEN_DEVICE_FUNC inline typename ParametrizedLine<Scalar_, AmbientDim_, Options_>::VectorType | 
|  | ParametrizedLine<Scalar_, AmbientDim_, Options_>::pointAt(const Scalar_& t) const { | 
|  | return origin() + (direction() * t); | 
|  | } | 
|  |  | 
|  | /** \returns the parameter value of the intersection between \c *this and the given \a hyperplane | 
|  | */ | 
|  | template <typename Scalar_, int AmbientDim_, int Options_> | 
|  | template <int OtherOptions> | 
|  | EIGEN_DEVICE_FUNC inline Scalar_ ParametrizedLine<Scalar_, AmbientDim_, Options_>::intersectionParameter( | 
|  | const Hyperplane<Scalar_, AmbientDim_, OtherOptions>& hyperplane) const { | 
|  | return -(hyperplane.offset() + hyperplane.normal().dot(origin())) / hyperplane.normal().dot(direction()); | 
|  | } | 
|  |  | 
|  | /** \deprecated use intersectionParameter() | 
|  | * \returns the parameter value of the intersection between \c *this and the given \a hyperplane | 
|  | */ | 
|  | template <typename Scalar_, int AmbientDim_, int Options_> | 
|  | template <int OtherOptions> | 
|  | EIGEN_DEVICE_FUNC inline Scalar_ ParametrizedLine<Scalar_, AmbientDim_, Options_>::intersection( | 
|  | const Hyperplane<Scalar_, AmbientDim_, OtherOptions>& hyperplane) const { | 
|  | return intersectionParameter(hyperplane); | 
|  | } | 
|  |  | 
|  | /** \returns the point of the intersection between \c *this and the given hyperplane | 
|  | */ | 
|  | template <typename Scalar_, int AmbientDim_, int Options_> | 
|  | template <int OtherOptions> | 
|  | EIGEN_DEVICE_FUNC inline typename ParametrizedLine<Scalar_, AmbientDim_, Options_>::VectorType | 
|  | ParametrizedLine<Scalar_, AmbientDim_, Options_>::intersectionPoint( | 
|  | const Hyperplane<Scalar_, AmbientDim_, OtherOptions>& hyperplane) const { | 
|  | return pointAt(intersectionParameter(hyperplane)); | 
|  | } | 
|  |  | 
|  | }  // end namespace Eigen | 
|  |  | 
|  | #endif  // EIGEN_PARAMETRIZEDLINE_H |