Ponca  2cfe00173bb12dda99e12b2b48a0e1f683bc5cdd
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;
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;
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;
52 return w;
53 }
54
55 template <class DataPoint, class _NFilter, typename T>
56 requires FUNDAMENTAL_FORM_WEINGARTEN_ESTIMATOR_REQUIREMENTS
57 template <typename Matrix2Derived>
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 requires NORMAL_DERIVATIVE_WEINGARTEN_ESTIMATOR_REQUIREMENTS
88 typename NormalDerivativeWeingartenEstimator<DataPoint, _NFilter, DiffType, T>::Matrix2
95
96 template <class DataPoint, class _NFilter, int DiffType, typename T>
97 requires NORMAL_DERIVATIVE_WEINGARTEN_ESTIMATOR_REQUIREMENTS
98 FIT_RESULT NormalDerivativeWeingartenEstimator<DataPoint, _NFilter, DiffType, T>::finalize()
99 {
100
101 PONCA_MULTIARCH_STD_MATH(abs);
102 PONCA_MULTIARCH_STD_MATH(sqrt);
103
104 using Index = typename VectorType::Index;
105
106 Base::finalize();
107 // Test if base finalize end on a viable case (stable / unstable)
108 if (this->isReady())
109 {
110 Index i0 = Index(-1), i1 = Index(-1), i2 = Index(-1);
111
112 MatrixType dN = Base::dNormal().template middleCols<DataPoint::Dim>(Base::isScaleDer() ? 1 : 0);
113
114 VectorType n = Base::primitiveGradient();
115 n.array().abs().minCoeff(&i0); // i0: dimension where n extends the least
116 i1 = (i0 + 1) % 3;
117 i2 = (i0 + 2) % 3;
118
119 m_tangentBasis.col(0) = n;
120
121 m_tangentBasis.col(1)[i0] = 0;
122 m_tangentBasis.col(1)[i1] = n[i2];
123 m_tangentBasis.col(1)[i2] = -n[i1];
124
125 m_tangentBasis.col(1).normalize();
126 m_tangentBasis.col(2) = m_tangentBasis.col(1).cross(n);
127 }
128 return Base::m_eCurrentState;
129 }
130
131 template <class DataPoint, class _NFilter, int DiffType, typename T>
132 requires NORMAL_DERIVATIVE_WEINGARTEN_ESTIMATOR_REQUIREMENTS
133 template <typename Matrix2Derived>
135 {
136 PONCA_MULTIARCH_STD_MATH(abs);
137 PONCA_MULTIARCH_STD_MATH(sqrt);
138
139 using Index = typename VectorType::Index;
140 using Matrix32 = Eigen::Matrix<Scalar, 3, 2>;
141
142 // Get the object space Weingarten map dN
143 MatrixType dN = Base::dNormal().template middleCols<DataPoint::Dim>(Base::isScaleDer() ? 1 : 0);
144
145 // Compute tangent-space change of basis function
146 auto B = m_tangentBasis.template rightCols<2>();
147
148 // Compute the 2x2 matrix representing the shape operator by transforming dN to the basis B.
149 // Recall that dN is a bilinear form, it thus transforms as follows:
150 W = B.transpose() * dN * B;
151
152 // Recall that at this stage, the shape operator represented by W describes the normal curvature K_n(u) in the
153 // direction u \in R^2 as follows:
154 // K_n(u) = u^T W u
155 // The principal curvatures are fully defined by the values and the directions of the extrema of K_n.
156 //
157 // 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
158 // symmetric matrices. In this case, the extrema of the previous quadratic form are directly obtained by the
159 // eigenvalue decomposition of W. However, if N(x) is only an approximation of the normal field of a surface,
160 // then N(x) is not necessarily curl-free, and in this case W is not symmetric. In this case, we first have to
161 // find an equivalent symmetric matrix W' such that:
162 // K_n(u) = u^T W' u,
163 // for any u \in R^2.
164 // It is easy to see that such a W' is simply obtained as:
165 // W' = (W + W^T)/2
166 W(0, 1) = W(1, 0) = (W(0, 1) + W(1, 0)) / Scalar(2);
167 }
168
169 template <class DataPoint, class _NFilter, int DiffType, typename T>
170 requires NORMAL_DERIVATIVE_WEINGARTEN_ESTIMATOR_REQUIREMENTS
173 const VectorType& _q, bool _isPositionVector) const
174 {
175 return m_tangentBasis.normalized().transpose() *
176 Base::getNeighborFrame().convertToLocalBasis(_q, _isPositionVector);
177 }
178
179 template <class DataPoint, class _NFilter, int DiffType, typename T>
180 requires NORMAL_DERIVATIVE_WEINGARTEN_ESTIMATOR_REQUIREMENTS
183 const VectorType& _lq, bool _isPositionVector) const
184 {
185 return Base::getNeighborFrame().convertToGlobalBasis(m_tangentBasis.normalized().transpose().inverse() * _lq,
186 _isPositionVector);
187 }
188
189 namespace internal
190 {
192 template <class DataPoint, class _NFilter, typename T>
193 requires WIENGARTEN_CURVATURE_ESTIMATOR_REQUIREMENTS
194 FIT_RESULT WeingartenCurvatureEstimatorBase<DataPoint, _NFilter, T>::finalize()
195 {
196 if (Base::finalize() != STABLE)
197 return Base::m_eCurrentState;
198
199 Matrix2 w;
200 Base::weingartenMap(w);
201 m_solver.computeDirect(w);
202
203 return Base::m_eCurrentState;
204 }
205 } // namespace internal
206} // namespace Ponca
207
Compute a Weingarten map from fundamental forms.
Definition weingarten.h:42
Scalar GaussianCurvature() const
Returns an estimate of the Gaussian curvature directly from the fundamental forms.
Scalar kMean() const
Returns an estimate of the mean curvature directly from the fundamental forms.
Matrix2 weingartenMap() const
Returns the Weingarten Map.
typename DataPoint::Scalar Scalar
Alias to scalar type.
Definition weingarten.h:43
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:112
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:113
typename DataPoint::Scalar Scalar
Alias to scalar type.
Definition weingarten.h:112
Matrix2 weingartenMap() const
Returns the Weingarten Map.
Copyright (c) 2022 Jacques-Olivier Lachaud (jacques-olivier.lachaud@univ-savoie.fr) Laboratory of Mat...
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