... @@ -11,6 +11,7 @@ ... @@ -11,6 +11,7 @@ #define _GRENAILLE_PLANE_ #define _GRENAILLE_PLANE_ #include "primitive.h" // PrimitiveBase #include "primitive.h" // PrimitiveBase #include namespace Grenaille namespace Grenaille { { ... @@ -24,28 +25,27 @@ namespace Grenaille ... @@ -24,28 +25,27 @@ namespace Grenaille \f$s_\mathbf{u}(\mathbf{x}) = \f$ s_\mathbf{u}(\mathbf{x}) = \left[ \mathbf{x}^T \; 1 \;\right]^T \cdot \mathbf{p} \f$. \left[ \mathbf{x}^T \; 1 \;\right]^T \cdot \mathbf{p} \f$. This class uses a compact storage of n+1 scalars in n-dimensionnal space. It This class inherits Eigen::Hyperplane. can be sensitive to the data scale, leading to potential instabilities due to round errors at large scales. \todo Add standard plane storing 2n scalars (direction and center). This primitive requires the definition of n-dimensionnal vectors This primitive requires the definition of n-dimensionnal vectors (VectorType) and homogeneous n-dimensionnal vectors (HVectorType) in (VectorType) in Concept::PointConcept. Concept::PointConcept. This primitive provides: This primitive provides: \verbatim PROVIDES_PLANE \endverbatim \verbatim PROVIDES_PLANE \endverbatim \note The first n-components of the plane must define a normalized vector */ */ template < class DataPoint, class _WFunctor, typename T = void > template < class DataPoint, class _WFunctor, typename T = void > class CompactPlane : public PrimitiveBase class CompactPlane : public PrimitiveBase, public Eigen::Hyperplane { { private: private: typedef PrimitiveBase Base; using Base = PrimitiveBase; public: /// \brief Specialization of Eigen::Hyperplane inherited by Grenaille::CompactPlane using EigenBase = Eigen::Hyperplane; protected: protected: ... @@ -62,21 +62,14 @@ public: ... @@ -62,21 +62,14 @@ public: typedef typename DataPoint::VectorType VectorType; typedef typename DataPoint::VectorType VectorType; /*! \brief Matrix type inherited from DataPoint */ /*! \brief Matrix type inherited from DataPoint */ typedef typename DataPoint::MatrixType MatrixType; typedef typename DataPoint::MatrixType MatrixType; /*! \brief Homogeneous vector type inherited from DataPoint */ typedef typename DataPoint::HVectorType HVectorType; /*! \brief Weight Function */ /*! \brief Weight Function */ typedef _WFunctor WFunctor; typedef _WFunctor WFunctor; // results public: HVectorType m_p; /*!< \brief Homogeneous plane representation */ public: public: /*! \brief Default constructor */ /*! \brief Default constructor */ MULTIARCH inline CompactPlane() MULTIARCH inline CompactPlane() : Base() : Base(), EigenBase() { { resetPrimitive(); resetPrimitive(); } } ... @@ -86,11 +79,12 @@ public: ... @@ -86,11 +79,12 @@ public: MULTIARCH inline void resetPrimitive() MULTIARCH inline void resetPrimitive() { { Base::resetPrimitive(); Base::resetPrimitive(); m_p = HVectorType::Zero(); EigenBase* cc = static_cast(this); *cc = EigenBase(); } } MULTIARCH inline bool operator==(const CompactPlane& other) const{ MULTIARCH inline bool operator==(const CompactPlane& other) const{ return m_p == other.m_p; return EigenBase::isApprox(other); } } /*! \brief Comparison operator, convenience function */ /*! \brief Comparison operator, convenience function */ ... @@ -99,36 +93,35 @@ public: ... @@ -99,36 +93,35 @@ public: } } /* \brief Init the plane from a direction and a position /* \brief Init the plane from a direction and a position \param _dir Orientation of the plane \param _dir Orientation of the plane, does not need to be normalized \param _pos Position of the plane \param _pos Position of the plane */ */ MULTIARCH inline void setPlane (const VectorType& _dir, MULTIARCH inline void setPlane (const VectorType& _dir, const VectorType& _pos) const VectorType& _pos) { { m_p.template head() = _dir.normalized(); EigenBase* cc = static_cast(this); m_p.template tail<1>()<< -_pos.dot(m_p.template head()); *cc = EigenBase(_dir.normalized(), _pos); } } //! \brief Value of the scalar field at the location \f$\mathbf{q} \f$ //! \brief Value of the scalar field at the location \f$\mathbf{q} \f$ MULTIARCH inline Scalar potential (const VectorType& _q) const MULTIARCH inline Scalar potential (const VectorType& _q) const { { // Project on the normal vector and add the offset value // The potential is the distance from the point to the plane return m_p.template head().dot(_q) + return EigenBase::signedDistance(_q); *( m_p.template tail<1>().data() ); } } //! \brief Project a point on the plane //! \brief Project a point on the plane MULTIARCH inline VectorType project (const VectorType& _q) const MULTIARCH inline VectorType project (const VectorType& _q) const { { // The potential is the distance from the point to the plane // Project on the normal vector and add the offset value return _q - potential(_q) * m_p.template head(); return EigenBase::projection(_q); } } //! \brief Scalar field gradient direction at \f$\mathbf{q}\f$ //! \brief Scalar field gradient direction at \f$\mathbf{q}\f$ MULTIARCH inline VectorType primitiveGradient (const VectorType&) const MULTIARCH inline VectorType primitiveGradient (const VectorType&) const { { // Uniform gradient defined only by the orientation of the plane // Uniform gradient defined only by the orientation of the plane return m_p.template head(); return EigenBase::normal(); } } ... ...