Ponca  4d2a58fa5c6375adef5c4b208f4d47e016cecd6d
Point Cloud Analysis library
Loading...
Searching...
No Matches
weingarten.hpp
1#include <Eigen/Eigenvalues>
2#include <Eigen/Core>
3
4namespace Ponca
5{
7 template <class DataPoint, class _NFilter, typename T>
8 requires FUNDAMENTAL_FORM_WEINGARTEN_ESTIMATOR_REQUIREMENTS
9 typename FundamentalFormWeingartenEstimator<DataPoint, _NFilter, T>::Matrix2 FundamentalFormWeingartenEstimator<
10 DataPoint, _NFilter, T>::firstFundamentalForm() const
11 {
12 Matrix2 first;
13 firstFundamentalForm(first);
14 return first;
15 }
16
17 template <class DataPoint, class _NFilter, typename T>
18 requires FUNDAMENTAL_FORM_WEINGARTEN_ESTIMATOR_REQUIREMENTS
19 template <typename Matrix2Derived>
21 {
22 Base::firstFundamentalFormComponents(first(0, 0), first(1, 0), first(1, 1));
23 first(0, 1) = first(1, 0); // diagonal
24 }
25
26 template <class DataPoint, class _NFilter, typename T>
27 requires FUNDAMENTAL_FORM_WEINGARTEN_ESTIMATOR_REQUIREMENTS
28 typename FundamentalFormWeingartenEstimator<DataPoint, _NFilter, T>::Matrix2 FundamentalFormWeingartenEstimator<
29 DataPoint, _NFilter, T>::secondFundamentalForm() const
30 {
31 Matrix2 second;
32 secondFundamentalForm(second);
33 return second;
34 }
35
36 template <class DataPoint, class _NFilter, typename T>
37 requires FUNDAMENTAL_FORM_WEINGARTEN_ESTIMATOR_REQUIREMENTS
38 template <typename Matrix2Derived>
40 {
41 Base::secondFundamentalFormComponents(second(0, 0), second(1, 0), second(1, 1));
42 second(0, 1) = second(1, 0); // diagonal
43 }
44
45 template <class DataPoint, class _NFilter, typename T>
46 requires FUNDAMENTAL_FORM_WEINGARTEN_ESTIMATOR_REQUIREMENTS
47 typename FundamentalFormWeingartenEstimator<DataPoint, _NFilter, T>::Matrix2 FundamentalFormWeingartenEstimator<
48 DataPoint, _NFilter, T>::weingartenMap() const
49 {
50 Matrix2 w;
51 weingartenMap(w);
52 return w;
53 }
54
55 template <class DataPoint, class _NFilter, typename T>
56 requires FUNDAMENTAL_FORM_WEINGARTEN_ESTIMATOR_REQUIREMENTS
57 template <typename Matrix2Derived>
59 {
60 w = firstFundamentalForm().inverse() * secondFundamentalForm();
61 }
62
63 template <class DataPoint, class _NFilter, typename T>
64 requires FUNDAMENTAL_FORM_WEINGARTEN_ESTIMATOR_REQUIREMENTS
66 DataPoint, _NFilter, T>::kMean() const
67 {
68 Scalar E, F, G, L, M, N;
69 Base::firstFundamentalFormComponents(E, F, G);
70 Base::secondFundamentalFormComponents(L, M, N);
71 return (G * L - Scalar(2) * F * M + E * N) / (Scalar(2) * (E * G - F * F));
72 }
73
74 template <class DataPoint, class _NFilter, typename T>
75 requires FUNDAMENTAL_FORM_WEINGARTEN_ESTIMATOR_REQUIREMENTS
77 DataPoint, _NFilter, T>::GaussianCurvature() const
78 {
79 Scalar E, F, G, L, M, N;
80 Base::firstFundamentalFormComponents(E, F, G);
81 Base::secondFundamentalFormComponents(L, M, N);
82 return (L * N - M * M) / (E * G - F * F);
83 }
84
86 template <class DataPoint, class _NFilter, int DiffType, typename T>
87 typename NormalDerivativeWeingartenEstimator<DataPoint, _NFilter, DiffType, T>::Matrix2
89 {
90 Matrix2 w;
91 weingartenMap(w);
92 return w;
93 }
94
95 template <class DataPoint, class _NFilter, int DiffType, typename T>
97 {
98
99 PONCA_MULTIARCH_STD_MATH(abs);
100 PONCA_MULTIARCH_STD_MATH(sqrt);
101
102 using Index = typename VectorType::Index;
103
104 Base::finalize();
105 // Test if base finalize end on a viable case (stable / unstable)
106 if (this->isReady())
107 {
108 Index i0 = Index(-1), i1 = Index(-1), i2 = Index(-1);
109
110 MatrixType dN = Base::dNormal().template middleCols<DataPoint::Dim>(Base::isScaleDer() ? 1 : 0);
111
112 VectorType n = Base::primitiveGradient();
113 n.array().abs().minCoeff(&i0); // i0: dimension where n extends the least
114 i1 = (i0 + 1) % 3;
115 i2 = (i0 + 2) % 3;
116
117 m_tangentBasis.col(0) = n;
118
119 m_tangentBasis.col(1)[i0] = 0;
120 m_tangentBasis.col(1)[i1] = n[i2];
121 m_tangentBasis.col(1)[i2] = -n[i1];
122
123 m_tangentBasis.col(1).normalize();
124 m_tangentBasis.col(2) = m_tangentBasis.col(1).cross(n);
125 }
126 return Base::m_eCurrentState;
127 }
128
129 template <class DataPoint, class _NFilter, int DiffType, typename T>
130 template <typename Matrix2Derived>
132 {
133 PONCA_MULTIARCH_STD_MATH(abs);
134 PONCA_MULTIARCH_STD_MATH(sqrt);
135
136 using Index = typename VectorType::Index;
137 using Matrix32 = Eigen::Matrix<Scalar, 3, 2>;
138
139 // Get the object space Weingarten map dN
140 MatrixType dN = Base::dNormal().template middleCols<DataPoint::Dim>(Base::isScaleDer() ? 1 : 0);
141
142 // Compute tangent-space change of basis function
143 auto B = m_tangentBasis.template rightCols<2>();
144
145 // Compute the 2x2 matrix representing the shape operator by transforming dN to the basis B.
146 // Recall that dN is a bilinear form, it thus transforms as follows:
147 W = B.transpose() * dN * B;
148
149 // Recall that at this stage, the shape operator represented by W describes the normal curvature K_n(u) in the
150 // direction u \in R^2 as follows:
151 // K_n(u) = u^T W u
152 // The principal curvatures are fully defined by the values and the directions of the extrema of K_n.
153 //
154 // If the normal field N(x) comes from the gradient of a scalar field, then N(x) is curl-free, and dN and W are
155 // symmetric matrices. In this case, the extrema of the previous quadratic form are directly obtained by the
156 // eigenvalue decomposition of W. However, if N(x) is only an approximation of the normal field of a surface,
157 // then N(x) is not necessarily curl-free, and in this case W is not symmetric. In this case, we first have to
158 // find an equivalent symmetric matrix W' such that:
159 // K_n(u) = u^T W' u,
160 // for any u \in R^2.
161 // It is easy to see that such a W' is simply obtained as:
162 // W' = (W + W^T)/2
163 W(0, 1) = W(1, 0) = (W(0, 1) + W(1, 0)) / Scalar(2);
164 }
165
166 template <class DataPoint, class _NFilter, int DiffType, typename T>
169 const VectorType& _q, bool _isPositionVector) const
170 {
171 return m_tangentBasis.normalized().transpose() *
172 Base::getNeighborFrame().convertToLocalBasis(_q, _isPositionVector);
173 }
174
175 template <class DataPoint, class _NFilter, int DiffType, typename T>
178 const VectorType& _lq, bool _isPositionVector) const
179 {
180 return Base::getNeighborFrame().convertToGlobalBasis(m_tangentBasis.normalized().transpose().inverse() * _lq,
182 }
183
184 namespace internal
185 {
187 template <class DataPoint, class _NFilter, typename T>
188 requires WIENGARTEN_CURVATURE_ESTIMATOR_REQUIREMENTS
190 {
191 if (Base::finalize() != STABLE)
192 return Base::m_eCurrentState;
193
194 Matrix2 w;
195 Base::weingartenMap(w);
196 m_solver.computeDirect(w);
197
198 return Base::m_eCurrentState;
199 }
200 } // namespace internal
201} // namespace Ponca
202
Aggregator class used to declare specialized structures using CRTP.
Definition basket.h:260
typename P::Scalar Scalar
Scalar type used for computation, as defined from template parameter P
Definition basket.h:268
Compute a Weingarten map from fundamental forms.
Definition weingarten.h:40
Matrix2 weingartenMap() const
Returns the Weingarten Map.
typename DataPoint::Scalar Scalar
Alias to scalar type.
Definition weingarten.h:41
Matrix2 secondFundamentalForm() const
Assembles and returns the second fundamental form from the base class.
Matrix2 firstFundamentalForm() const
Assembles and returns the first fundamental form from the base class.
typename Base::VectorType VectorType
Alias to vector type.
Definition weingarten.h:110
VectorType tangentPlaneToWorld(const VectorType &_q, bool _isPositionVector=true) const
Transform a point from the tangent plane [h, u, v]^T to ambient space.
VectorType worldToTangentPlane(const VectorType &_q, bool _isPositionVector=true) const
Express a point in ambient space relatively to the tangent plane.
typename DataPoint::MatrixType MatrixType
Alias to matrix type.
Definition weingarten.h:111
Matrix2 weingartenMap() const
Returns the Weingarten Map.
FIT_RESULT finalize()
Finalize the procedure.
FIT_RESULT finalize()
Finalize the procedure.
This Source Code Form is subject to the terms of the Mozilla Public License, v.
Definition concepts.h:11
FIT_RESULT
Enum corresponding to the state of a fitting method (and what the finalize function returns)
Definition enums.h:15
@ STABLE
The fitting is stable and ready to use.
Definition enums.h:17