Ponca  97e1aa5c56f0b8ca113a6b95d36cc3b5cde35a4e
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#pragma once
8
9#include "../../defines.h"
10#include "../concepts.h"
11#include "../../Filters/concepts.h" // HasLocalFrame
12
13#include PONCA_MULTIARCH_INCLUDE_STD(cmath)
14#include PONCA_MULTIARCH_INCLUDE_CU_STD(limits)
15
16#include <Eigen/Core>
17
18#define ALGEBRAIC_SPHERE_REQUIREMENTS ProvidesBasketUnitBase<T>&& HasLocalFrame<_NFilter>
19
20namespace Ponca
21{
45 template <class DataPoint, class _NFilter, typename T>
46 requires ALGEBRAIC_SPHERE_REQUIREMENTS
47 class AlgebraicSphere : public T
48 {
49 PONCA_FITTING_DECLARE_DEFAULT_TYPES
50
51 protected:
53 bool m_isNormalized{false};
54
55 // results
56 public:
58 m_uq{0};
59 VectorType m_ul{VectorType::Zero()};
61 public:
62 PONCA_EXPLICIT_BASKET_CAST_OPERATORS(AlgebraicSphere, algebraicSphere)
63 PONCA_EXPLICIT_BASKET_CAST_OPERATORS(AlgebraicSphere, implicitPrimitive)
64 PONCA_EXPLICIT_BASKET_CAST_OPERATORS(AlgebraicSphere, projectionOperator)
65 PONCA_EXPLICIT_BASKET_CAST_OPERATORS(AlgebraicSphere, meanCurvature)
66
71 PONCA_MULTIARCH inline void init()
72 {
73 Base::init();
74
75 m_uc = Scalar(0);
76 m_ul = VectorType::Zero();
77 m_uq = Scalar(0);
78
79 m_isNormalized = false;
80 }
81
85 PONCA_MULTIARCH [[nodiscard]] inline bool isValid() const
86 {
87 return !(m_ul.isApprox(VectorType::Zero()) && m_uc == Scalar(0) && m_uq == Scalar(0));
88 }
89
91 PONCA_MULTIARCH inline bool operator==(const AlgebraicSphere<DataPoint, NeighborFilter, T>& other) const
92 {
93 PONCA_MULTIARCH_STD_MATH(pow);
94 const Scalar epsilon = Eigen::NumTraits<Scalar>::dummy_precision();
95 const Scalar squaredEpsilon = epsilon * epsilon;
96 return pow(m_uc - other.m_uc, Scalar(2)) < squaredEpsilon &&
97 pow(m_uq - other.m_uq, Scalar(2)) < squaredEpsilon && m_ul.isApprox(other.m_ul);
98 }
99
101 template <typename Other>
102 PONCA_MULTIARCH [[nodiscard]] inline bool isApprox(
103 const Other& other, const Scalar& epsilon = Eigen::NumTraits<Scalar>::dummy_precision()) const
104 {
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 && m_ul.isApprox(other.m_ul);
109 }
110
112 PONCA_MULTIARCH inline bool operator!=(const AlgebraicSphere<DataPoint, NeighborFilter, T>& other) const
113 {
114 return !((*this) == other);
115 }
116
149 PONCA_MULTIARCH inline void changeBasis(const VectorType& newbasis)
150 {
151 auto& frame = Base::getNeighborFrame();
152
153 VectorType diff = frame.center() - newbasis;
154 frame.changeNeighborhoodFrame(newbasis);
155 Base::init();
156 m_uc = m_uc - m_ul.dot(diff) + m_uq * diff.dot(diff);
157 m_ul = m_ul - Scalar(2.) * m_uq * diff;
158 // m_uq is not changed
159 m_isNormalized = false;
161 }
162
164 PONCA_MULTIARCH [[nodiscard]] inline Scalar prattNorm() const
165 {
166 PONCA_MULTIARCH_STD_MATH(sqrt);
167 return sqrt(prattNorm2());
168 }
169
171 PONCA_MULTIARCH [[nodiscard]] inline Scalar prattNorm2() const
172 {
173 return m_ul.squaredNorm() - Scalar(4.) * m_uc * m_uq;
174 }
175
180 PONCA_MULTIARCH inline bool applyPrattNorm()
181 {
182 if (!m_isNormalized)
183 {
184 Scalar pn = prattNorm();
185 m_uc /= pn;
186 m_ul *= Scalar(1.) / pn;
187 m_uq /= pn;
188
189 m_isNormalized = true;
190 }
191 return true;
192 }
193
198 PONCA_MULTIARCH [[nodiscard]] inline Scalar radius() const
199 {
200 PONCA_MULTIARCH_CU_STD_FUNC(numeric_limits);
201 if (isPlane())
202 return numeric_limits<Scalar>::infinity(); // non-sense value
203
204 PONCA_MULTIARCH_STD_MATH(sqrt);
205 Scalar b = Scalar(1.) / m_uq;
206 return Scalar(sqrt(((Scalar(-0.5) * b) * m_ul).squaredNorm() - m_uc * b));
207 }
208
209 PONCA_MULTIARCH [[nodiscard]] inline Scalar kMean() const { return isPlane() ? Scalar(0) : Scalar(2) * m_uq; }
210
215 PONCA_MULTIARCH [[nodiscard]] inline VectorType center() const
216 {
217 PONCA_MULTIARCH_CU_STD_FUNC(numeric_limits);
218 if (isPlane())
219 return VectorType::Constant(numeric_limits<Scalar>::infinity()); // non-sense value
220
221 Scalar b = Scalar(1.) / m_uq;
222 return Base::getNeighborFrame().convertToGlobalBasis((Scalar(-0.5) * b) * m_ul);
223 }
224
226 PONCA_MULTIARCH [[nodiscard]] inline bool isNormalized() const { return m_isNormalized; }
227
230 PONCA_MULTIARCH [[nodiscard]] inline Scalar potential(const VectorType& _q) const
231 {
232 // Turn to centered basis
233 const VectorType lq = Base::getNeighborFrame().convertToLocalBasis(_q);
234 return potentialLocal(lq);
235 }
236
239 PONCA_MULTIARCH [[nodiscard]] inline Scalar potential() const { return m_uc; }
240
249 PONCA_MULTIARCH [[nodiscard]] inline VectorType project(const VectorType& _q) const;
250
253 PONCA_MULTIARCH [[nodiscard]] inline VectorType primitiveGradient(const VectorType& _q) const
254 {
255 // Turn to centered basis
256 const VectorType lq = Base::getNeighborFrame().convertToLocalBasis(_q);
257 return primitiveGradientLocal(lq);
258 }
259
262 PONCA_MULTIARCH [[nodiscard]] inline const VectorType& primitiveGradient() const { return m_ul; }
263
268 PONCA_MULTIARCH [[nodiscard]] inline bool isPlane() const
269 {
270 PONCA_MULTIARCH_STD_MATH(abs);
271 bool bPlanar = Eigen::internal::isApprox(m_uq, Scalar(0));
272 bool bReady = Base::isReady();
273 return bReady && bPlanar;
274 }
275
276 protected:
278 PONCA_MULTIARCH [[nodiscard]] inline Scalar potentialLocal(const VectorType& _lq) const;
279
281 PONCA_MULTIARCH [[nodiscard]] inline VectorType primitiveGradientLocal(const VectorType& _lq) const;
282 }; // class AlgebraicSphere
283
284#include "algebraicSphere.hpp"
285} // namespace Ponca
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.
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.
AlgebraicSphere< DataPoint, _NFilter, T > & projectionOperator()
Explicit conversion to CLASSNAME, to access methods potentially hidden by heritage.
AlgebraicSphere< DataPoint, _NFilter, T > & implicitPrimitive()
Explicit conversion to CLASSNAME, to access methods potentially hidden by heritage.
AlgebraicSphere< DataPoint, _NFilter, T > & meanCurvature()
Explicit conversion to CLASSNAME, to access methods potentially hidden by heritage.
VectorType primitiveGradientLocal(const VectorType &_lq) const
Approximation of the scalar field gradient at .
Scalar m_uq
Quadratic parameter of the Algebraic hyper-sphere.
Scalar m_uc
Constant parameter of the Algebraic hyper-sphere.
typename DataPoint::Scalar Scalar
Alias to scalar type.
AlgebraicSphere< DataPoint, _NFilter, T > & algebraicSphere()
Explicit conversion to CLASSNAME, to access methods potentially hidden by heritage.
bool operator!=(const AlgebraicSphere< DataPoint, NeighborFilter, T > &other) const
Comparison operator, convenience function.
Scalar potentialLocal(const VectorType &_lq) const
Value of the scalar field at the location .
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.
VectorType project(const VectorType &_q) const
Project a point on the algebraic hypersphere.
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.
Definition concepts.h:11