Ponca  7d8ac87a7de01d881c9fde3c42e397b44bffb901
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
11#include PONCA_MULTIARCH_INCLUDE_STD(cmath)
12#include PONCA_MULTIARCH_INCLUDE_CU_STD(limits)
13
14#include <Eigen/Core>
15
16namespace Ponca
17{
18
43 template <class DataPoint, class _NFilter, typename T>
44 class AlgebraicSphere : public T
45 {
46 PONCA_FITTING_DECLARE_DEFAULT_TYPES
47 static_assert(_NFilter::hasLocalFrame, "AlgebraicSphere requires local frame");
48
49 protected:
50 enum
51 {
52 check = Base::PROVIDES_PRIMITIVE_BASE,
54 };
55
56 protected:
58 bool m_isNormalized{false};
59
60 // results
61 public:
63 m_uq{0};
64 VectorType m_ul{VectorType::Zero()};
66 public:
67 PONCA_EXPLICIT_CAST_OPERATORS(AlgebraicSphere, algebraicSphere)
68
69
73 PONCA_MULTIARCH inline void init()
74 {
75 Base::init();
76
77 m_uc = Scalar(0);
78 m_ul = VectorType::Zero();
79 m_uq = Scalar(0);
80
81 m_isNormalized = false;
82 }
83
87 PONCA_MULTIARCH [[nodiscard]] inline bool isValid() const
88 {
89 return !(m_ul.isApprox(VectorType::Zero()) && m_uc == Scalar(0) && m_uq == Scalar(0));
90 }
91
93 PONCA_MULTIARCH inline bool operator==(const AlgebraicSphere<DataPoint, NeighborFilter, T>& other) const
94 {
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 && m_ul.isApprox(other.m_ul);
100 }
102 template <typename Other>
103 PONCA_MULTIARCH [[nodiscard]] inline bool isApprox(
104 const Other& other, const Scalar& epsilon = Eigen::NumTraits<Scalar>::dummy_precision()) const
105 {
106 PONCA_MULTIARCH_STD_MATH(pow);
107 const Scalar squaredEpsilon = epsilon * epsilon;
108 return pow(m_uc - other.m_uc, Scalar(2)) < squaredEpsilon &&
109 pow(m_uq - other.m_uq, Scalar(2)) < squaredEpsilon && m_ul.isApprox(other.m_ul);
110 }
111
113 PONCA_MULTIARCH inline bool operator!=(const AlgebraicSphere<DataPoint, NeighborFilter, T>& other) const
114 {
115 return !((*this) == other);
116 }
117
150 PONCA_MULTIARCH inline void changeBasis(const VectorType& newbasis)
151 {
152 VectorType diff = Base::getNeighborFilter().evalPos() - newbasis;
153 Base::m_nFilter.changeNeighborhoodFrame(newbasis);
154 Base::init();
155 m_uc = m_uc - m_ul.dot(diff) + m_uq * diff.dot(diff);
156 m_ul = m_ul - Scalar(2.) * m_uq * diff;
157 // m_uq is not changed
158 m_isNormalized = false;
160 }
161
163 PONCA_MULTIARCH [[nodiscard]] inline Scalar prattNorm() const
164 {
165 PONCA_MULTIARCH_STD_MATH(sqrt);
166 return sqrt(prattNorm2());
167 }
168
170 PONCA_MULTIARCH [[nodiscard]] inline Scalar prattNorm2() const
171 {
172 return m_ul.squaredNorm() - Scalar(4.) * m_uc * m_uq;
173 }
174
179 PONCA_MULTIARCH inline bool applyPrattNorm()
180 {
181 if (!m_isNormalized)
182 {
183 Scalar pn = prattNorm();
184 m_uc /= pn;
185 m_ul *= Scalar(1.) / pn;
186 m_uq /= pn;
187
188 m_isNormalized = true;
189 }
190 return true;
191 }
192
197 PONCA_MULTIARCH [[nodiscard]] inline Scalar radius() const
198 {
199 PONCA_MULTIARCH_CU_STD_FUNC(numeric_limits);
200 if (isPlane())
201 return numeric_limits<Scalar>::infinity(); // non-sense value
202
203 PONCA_MULTIARCH_STD_MATH(sqrt);
204 Scalar b = Scalar(1.) / m_uq;
205 return Scalar(sqrt(((Scalar(-0.5) * b) * m_ul).squaredNorm() - m_uc * b));
206 }
207
212 PONCA_MULTIARCH [[nodiscard]] inline VectorType center() const
213 {
214 PONCA_MULTIARCH_CU_STD_FUNC(numeric_limits);
215 if (isPlane())
216 return VectorType::Constant(numeric_limits<Scalar>::infinity()); // non-sense value
217
218 Scalar b = Scalar(1.) / m_uq;
219 return Base::getNeighborFilter().convertToGlobalBasis((Scalar(-0.5) * b) * m_ul);
220 }
221
223 PONCA_MULTIARCH [[nodiscard]] inline bool isNormalized() const { return m_isNormalized; }
224
227 PONCA_MULTIARCH [[nodiscard]] inline Scalar potential(const VectorType& _q) const
228 {
229 // Turn to centered basis
230 const VectorType lq = Base::getNeighborFilter().convertToLocalBasis(_q);
231 return potentialLocal(lq);
232 }
233
236 PONCA_MULTIARCH [[nodiscard]] inline Scalar potential() const { return m_uc; }
237
246 PONCA_MULTIARCH [[nodiscard]] inline VectorType project(const VectorType& _q) const;
247
250 PONCA_MULTIARCH [[nodiscard]] inline VectorType primitiveGradient(const VectorType& _q) const
251 {
252 // Turn to centered basis
253 const VectorType lq = Base::getNeighborFilter().convertToLocalBasis(_q);
255 }
256
259 PONCA_MULTIARCH [[nodiscard]] inline const VectorType& primitiveGradient() const { return m_ul; }
260
265 PONCA_MULTIARCH [[nodiscard]] inline bool isPlane() const
266 {
267 PONCA_MULTIARCH_STD_MATH(abs);
268 bool bPlanar = Eigen::internal::isApprox(m_uq, Scalar(0));
269 bool bReady = Base::isReady();
270 return bReady && bPlanar;
271 }
272
273 protected:
275 PONCA_MULTIARCH [[nodiscard]] inline Scalar potentialLocal(const VectorType& _lq) const;
276
278 PONCA_MULTIARCH [[nodiscard]] inline VectorType primitiveGradientLocal(const VectorType& _lq) const;
279 }; // class AlgebraicSphere
280
281#include "algebraicSphere.hpp"
282} // 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.
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 .
@ check
Requires PrimitiveBase.
@ PROVIDES_ALGEBRAIC_SPHERE
Provides Algebraic Sphere.
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.
Aggregator class used to declare specialized structures using CRTP.
Definition basket.h:318
This Source Code Form is subject to the terms of the Mozilla Public License, v.