Ponca  b63e69866b9b277a96802d3d06e6492d50ffc055
Point Cloud Analysis library
Loading...
Searching...
No Matches
algebraicSphere.h
1/*
2 This Source Code Form is subject to the terms of the Mozilla Public
3 License, v. 2.0. If a copy of the MPL was not distributed with this
4 file, You can obtain one at http://mozilla.org/MPL/2.0/.
5*/
6
7
8#pragma once
9
10#include "./defines.h"
11
12#include PONCA_MULTIARCH_INCLUDE_STD(cmath)
13#include PONCA_MULTIARCH_INCLUDE_STD(limits)
14
15#include <Eigen/Core>
16
17namespace Ponca
18{
19
45template < class DataPoint, class _NFilter, typename T >
46class AlgebraicSphere : public T
47{
48 PONCA_FITTING_DECLARE_DEFAULT_TYPES
49 static_assert(_NFilter::hasLocalFrame, "AlgebraicSphere requires local frame");
50
51protected:
52 enum
53 {
54 check = Base::PROVIDES_PRIMITIVE_BASE,
56 };
57
58protected:
60 bool m_isNormalized {false};
61
62// results
63public:
65 m_uq {0};
66 VectorType m_ul {VectorType::Zero()};
68public:
69 PONCA_EXPLICIT_CAST_OPERATORS(AlgebraicSphere,algebraicSphere)
70
71
75 PONCA_MULTIARCH inline void init()
76 {
77 Base::init();
78
79 m_uc = Scalar(0);
80 m_ul = VectorType::Zero();
81 m_uq = Scalar(0);
82
83 m_isNormalized = false;
84 }
85
89 PONCA_MULTIARCH [[nodiscard]] inline bool isValid() const{
90 return !( m_ul.isApprox(VectorType::Zero()) && m_uc == Scalar(0) && m_uq == Scalar(0) );
91 }
92
94 PONCA_MULTIARCH inline bool operator==(const AlgebraicSphere<DataPoint, NeighborFilter, T>& other) const{
95 PONCA_MULTIARCH_STD_MATH(pow);
96 const Scalar epsilon = Eigen::NumTraits<Scalar>::dummy_precision();
97 const Scalar squaredEpsilon = epsilon*epsilon;
98 return pow(m_uc - other.m_uc, Scalar(2)) < squaredEpsilon &&
99 pow(m_uq - other.m_uq, Scalar(2)) < squaredEpsilon &&
100 m_ul.isApprox(other.m_ul);
101 }
103 template<typename Other>
104 PONCA_MULTIARCH [[nodiscard]] inline bool isApprox(const Other& other, const Scalar& epsilon = Eigen::NumTraits<Scalar>::dummy_precision()) const{
105 PONCA_MULTIARCH_STD_MATH(pow);
106 const Scalar squaredEpsilon = epsilon*epsilon;
107 return pow(m_uc - other.m_uc, Scalar(2)) < squaredEpsilon &&
108 pow(m_uq - other.m_uq, Scalar(2)) < squaredEpsilon &&
109 m_ul.isApprox(other.m_ul);
110 }
111
112
114 PONCA_MULTIARCH inline bool operator!=(const AlgebraicSphere<DataPoint, NeighborFilter, T>& other) const{
115 return ! ((*this) == other);
116 }
117
147 PONCA_MULTIARCH inline void changeBasis(const VectorType& newbasis)
148 {
149 VectorType diff = Base::getNeighborFilter().evalPos() - newbasis;
150 Base::getNeighborFilter().changeNeighborhoodFrame(newbasis);
151 Base::init();
152 m_uc = m_uc - m_ul.dot(diff) + m_uq * diff.dot(diff);
153 m_ul = m_ul - Scalar(2.)*m_uq*diff;
154 //m_uq is not changed
155 m_isNormalized = false;
157 }
158
160 PONCA_MULTIARCH [[nodiscard]] inline Scalar prattNorm() const
161 {
162 PONCA_MULTIARCH_STD_MATH(sqrt);
163 return sqrt(prattNorm2());
164 }
165
167 PONCA_MULTIARCH [[nodiscard]] inline Scalar prattNorm2() const
168 {
169 return m_ul.squaredNorm() - Scalar(4.) * m_uc * m_uq;
170 }
171
176 PONCA_MULTIARCH inline bool applyPrattNorm()
177 {
178 if (! m_isNormalized)
179 {
180 Scalar pn = prattNorm();
181 m_uc /= pn;
182 m_ul *= Scalar(1.)/pn;
183 m_uq /= pn;
184
185 m_isNormalized = true;
186 }
187 return true;
188 }
189
194 PONCA_MULTIARCH [[nodiscard]] inline Scalar radius() const
195 {
196 PONCA_MULTIARCH_STD_MATH(numeric_limits);
197 if(isPlane())
198 return numeric_limits<Scalar>::infinity(); // non-sense value
199
200 PONCA_MULTIARCH_STD_MATH(sqrt);
201 Scalar b = Scalar(1.)/m_uq;
202 return Scalar(sqrt( ((Scalar(-0.5)*b)*m_ul).squaredNorm() - m_uc*b ));
203 }
204
209 PONCA_MULTIARCH [[nodiscard]] inline VectorType center() const
210 {
211 PONCA_MULTIARCH_STD_MATH(numeric_limits);
212 if(isPlane())
213 return VectorType::Constant(numeric_limits<Scalar>::infinity()); // non-sense value
214
215 Scalar b = Scalar(1.)/m_uq;
216 return Base::getNeighborFilter().convertToGlobalBasis((Scalar(-0.5)*b)*m_ul);
217 }
218
220 PONCA_MULTIARCH [[nodiscard]] inline bool isNormalized() const { return m_isNormalized; }
221
224 PONCA_MULTIARCH [[nodiscard]] inline Scalar potential (const VectorType& _q) const
225 {
226 // Turn to centered basis
227 const VectorType lq = Base::getNeighborFilter().convertToLocalBasis(_q);
228 return potentialLocal(lq);
229 }
230
233 PONCA_MULTIARCH [[nodiscard]] inline Scalar potential() const { return m_uc; }
234
243 PONCA_MULTIARCH [[nodiscard]] inline VectorType project (const VectorType& _q) const;
244
247 PONCA_MULTIARCH [[nodiscard]] inline VectorType primitiveGradient (const VectorType& _q) const
248 {
249 // Turn to centered basis
250 const VectorType lq = Base::getNeighborFilter().convertToLocalBasis(_q);
251 return primitiveGradientLocal(lq);
252 }
253
256 PONCA_MULTIARCH [[nodiscard]] inline const VectorType& primitiveGradient () const { return m_ul; }
257
262 PONCA_MULTIARCH [[nodiscard]] inline bool isPlane() const
263 {
264 PONCA_MULTIARCH_STD_MATH(abs);
265 bool bPlanar = Eigen::internal::isApprox(m_uq,Scalar(0));
266 bool bReady = Base::isReady();
267 return bReady && bPlanar;
268 }
269
270protected:
272 PONCA_MULTIARCH [[nodiscard]] inline Scalar potentialLocal (const VectorType& _lq) const;
273
275 PONCA_MULTIARCH [[nodiscard]] inline VectorType primitiveGradientLocal (const VectorType& _lq) const;
276}; //class AlgebraicSphere
277
278#include "algebraicSphere.hpp"
279}
Algebraic Sphere primitive.
Scalar potential() const
Value of the scalar field at the evaluation point.
VectorType center() const
return the estimated center of the sphere
bool applyPrattNorm()
Normalize the scalar field by the Pratt norm.
void changeBasis(const VectorType &newbasis)
Express the scalar field relatively to a new basis.
@ check
Requires PrimitiveBase.
@ PROVIDES_ALGEBRAIC_SPHERE
Provides Algebraic Sphere.
const VectorType & primitiveGradient() const
Approximation of the scalar field gradient at the evaluation point.
void init()
Set the scalar field values to 0 and reset the isNormalized() status.
Scalar m_uq
Quadratic parameter of the Algebraic hyper-sphere.
VectorType project(const VectorType &_q) const
Project a point on the algebraic hypersphere.
Scalar m_uc
Constant parameter of the Algebraic hyper-sphere.
typename DataPoint::Scalar Scalar
Alias to scalar type.
Scalar potentialLocal(const VectorType &_lq) const
Value of the scalar field at the location .
VectorType primitiveGradientLocal(const VectorType &_lq) const
Approximation of the scalar field gradient at .
AlgebraicSphere< DataPoint, _NFilter, T > & algebraicSphere()
Explicit conversion to AlgebraicSphere , to access methods potentially hidden by heritage.
bool operator!=(const AlgebraicSphere< DataPoint, NeighborFilter, T > &other) const
Comparison operator, convenience function.
bool m_isNormalized
Is the implicit scalar field normalized using Pratt.
Scalar prattNorm2() const
compute the squared Pratt norm of the implicit scalar field.
bool isApprox(const Other &other, const Scalar &epsilon=Eigen::NumTraits< Scalar >::dummy_precision()) const
Approximate operator.
Scalar prattNorm() const
compute the Pratt norm of the implicit scalar field.
Scalar radius() const
return the estimated radius of the sphere
VectorType m_ul
Linear parameter of the Algebraic hyper-sphere.
typename Base::VectorType VectorType
Alias to vector type.
bool isValid() const
Tell if the sphere as been correctly set. Used to set CONFLICT_ERROR_FOUND during fitting.
bool isPlane() const
Used to know if the fitting result to a plane.
Scalar potential(const VectorType &_q) const
Value of the scalar field at the location .
VectorType primitiveGradient(const VectorType &_q) const
Approximation of the scalar field gradient at .
bool isNormalized() const
State indicating when the sphere has been normalized.
bool operator==(const AlgebraicSphere< DataPoint, NeighborFilter, T > &other) const
Comparison operator.
This Source Code Form is subject to the terms of the Mozilla Public License, v.