Ponca  7b3f8ad3fde25a027e6452783ccee143798a71b8
Point Cloud Analysis library
Loading...
Searching...
No Matches
mlsSphereFitDer.hpp
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
7template <class DataPoint, class _NFilter, int DiffType, typename T>
8 requires MLS_SPHERE_FIT_DER_REQUIREMENTS
10{
11 Base::init();
12
13 m_d2Uc = Matrix::Zero(), m_d2Uq = Matrix::Zero();
14 m_d2Ul = MatrixArray::Zero();
15
16 m_d2SumDotPN = Matrix::Zero();
17 m_d2SumDotPP = Matrix::Zero();
18 m_d2SumW = Matrix::Zero();
19
20 m_d2SumP = MatrixArray::Zero();
21 m_d2SumN = MatrixArray::Zero();
22}
23
24template <class DataPoint, class _NFilter, int DiffType, typename T>
25 requires MLS_SPHERE_FIT_DER_REQUIREMENTS
27 const DataPoint& attributes, ScalarArray& dw)
28{
29 Base::addLocalNeighbor(w, localQ, attributes, dw);
30 // compute weight derivatives
31 Matrix d2w = Matrix::Zero();
32
33 if (Base::isScaleDer())
34 d2w(0, 0) = Base::getNeighborFilter().scaled2w(attributes.pos(), attributes);
35
36 if (Base::isSpaceDer())
37 d2w.template bottomRightCorner<Dim, Dim>() = Base::getNeighborFilter().spaced2w(attributes.pos(), attributes);
38
39 if (Base::isScaleDer() && Base::isSpaceDer())
40 {
41 d2w.template bottomLeftCorner<Dim, 1>() = Base::getNeighborFilter().scaleSpaced2w(attributes.pos(), attributes);
42 d2w.template topRightCorner<1, Dim>() = d2w.template bottomLeftCorner<Dim, 1>().transpose();
43 }
44
45 m_d2SumDotPN += d2w * attributes.normal().dot(localQ);
46 m_d2SumDotPP += d2w * localQ.squaredNorm();
47 m_d2SumW += d2w;
48
49 for (int i = 0; i < Dim; ++i)
50 {
51 m_d2SumP.template block<DerDim, DerDim>(0, i * DerDim) += d2w * localQ[i];
52 m_d2SumN.template block<DerDim, DerDim>(0, i * DerDim) += d2w * attributes.normal()[i];
53 }
54}
55
56template <class DataPoint, class _NFilter, int DiffType, typename T>
57 requires MLS_SPHERE_FIT_DER_REQUIREMENTS
59{
60 Base::finalize();
61
62 if (this->isReady())
63 {
64 Matrix sumdSumPdSumN = Matrix::Zero();
65 Matrix sumd2SumPdSumN = Matrix::Zero();
66 Matrix sumd2SumNdSumP = Matrix::Zero();
67 Matrix sumdSumPdSumP = Matrix::Zero();
68 Matrix sumd2SumPdSumP = Matrix::Zero();
69
70 for (int i = 0; i < Dim; ++i)
71 {
72 sumdSumPdSumN += Base::m_dSumN.row(i).transpose() * Base::m_dSumP.row(i);
73 sumd2SumPdSumN += m_d2SumP.template block<DerDim, DerDim>(0, i * DerDim) * Base::m_sumN(i);
74 sumd2SumNdSumP += m_d2SumN.template block<DerDim, DerDim>(0, i * DerDim) * Base::m_sumP(i);
75 sumdSumPdSumP += Base::m_dSumP.row(i).transpose() * Base::m_dSumP.row(i);
76 sumd2SumPdSumP += m_d2SumP.template block<DerDim, DerDim>(0, i * DerDim) * Base::m_sumP(i);
77 }
78
79 Scalar invSumW = Scalar(1.) / Base::getWeightSum();
80
82 m_d2SumDotPN -
84 (Base::getWeightSum() * Base::getWeightSum() *
85 (Base::getWeightSum() *
87 Base::m_dSumW.transpose() *
88 (Base::m_sumN.transpose() * Base::m_dSumP + Base::m_sumP.transpose() * Base::m_dSumN) -
89 (Base::m_sumP.transpose() * Base::m_sumN) * m_d2SumW.transpose() -
90 (Base::m_dSumN.transpose() * Base::m_sumP + Base::m_dSumP.transpose() * Base::m_sumN) *
91 Base::m_dSumW) -
92 Scalar(2.) * Base::getWeightSum() * Base::m_dSumW.transpose() *
93 (Base::getWeightSum() *
94 (Base::m_sumN.transpose() * Base::m_dSumP + Base::m_sumP.transpose() * Base::m_dSumN) -
95 (Base::m_sumP.transpose() * Base::m_sumN) * Base::m_dSumW));
96
97 Matrix d2Deno = m_d2SumDotPP -
99 (Base::getWeightSum() * Base::getWeightSum() *
100 (Scalar(2.) * Base::getWeightSum() * (sumdSumPdSumP + sumd2SumPdSumP) +
101 Scalar(2.) * Base::m_dSumW.transpose() * (Base::m_sumP.transpose() * Base::m_dSumP) -
102 (Base::m_sumP.transpose() * Base::m_sumP) * m_d2SumW.transpose() -
103 Scalar(2.) * (Base::m_dSumP.transpose() * Base::m_sumP) * Base::m_dSumW) -
104 Scalar(2.) * Base::getWeightSum() * Base::m_dSumW.transpose() *
105 (Scalar(2.) * Base::getWeightSum() * Base::m_sumP.transpose() * Base::m_dSumP -
106 (Base::m_sumP.transpose() * Base::m_sumP) * Base::m_dSumW));
107
108 Scalar deno2 = Base::m_deno * Base::m_deno;
109
110 m_d2Uq = Scalar(.5) / (deno2 * deno2) *
111 (deno2 * (Base::m_dDeno.transpose() * Base::m_dNume + Base::m_deno * d2Nume -
112 Base::m_dNume.transpose() * Base::m_dDeno - Base::m_nume * d2Deno) -
113 Scalar(2.) * Base::m_deno * Base::m_dDeno.transpose() *
114 (Base::m_deno * Base::m_dNume - Base::m_nume * Base::m_dDeno));
115
116 for (int i = 0; i < Dim; ++i)
117 {
118 m_d2Ul.template block<DerDim, DerDim>(0, i * DerDim) =
119 invSumW * (m_d2SumN.template block<DerDim, DerDim>(0, i * DerDim) -
120 Scalar(2.) * (m_d2Uq * Base::m_sumP[i] + Base::m_dSumP.row(i).transpose() * Base::m_dUq +
121 Base::m_uq * m_d2SumP.template block<DerDim, DerDim>(0, i * DerDim) +
122 Base::m_dUq.transpose() * Base::m_dSumP.row(i)) -
123 Base::m_ul[i] * m_d2SumW - Base::m_dUl.row(i).transpose() * Base::m_dSumW -
124 Base::m_dSumW.transpose() * Base::m_dUl.row(i));
125 }
126
127 Matrix sumdUldSumP = Matrix::Zero();
128 Matrix sumUld2SumP = Matrix::Zero();
129 Matrix sumd2UlsumP = Matrix::Zero();
130 Matrix sumdSumPdUl = Matrix::Zero();
131
132 for (int i = 0; i < Dim; ++i)
133 {
134 sumdUldSumP += Base::m_dUl.row(i).transpose() * Base::m_dSumP.row(i);
135 sumUld2SumP += Base::m_ul[i] * m_d2SumP.template block<DerDim, DerDim>(0, i * DerDim);
136 sumd2UlsumP += m_d2Ul.template block<DerDim, DerDim>(0, i * DerDim) * Base::m_sumP[i];
137 sumdSumPdUl += Base::m_dSumP.row(i).transpose() * Base::m_dUl.row(i);
138 }
139
140 m_d2Uc =
141 -invSumW *
142 (sumdUldSumP + sumUld2SumP + sumd2UlsumP + sumdSumPdUl + Base::m_dUq.transpose() * Base::m_dSumDotPP +
143 Base::m_uq * m_d2SumDotPP + Base::m_dSumDotPP.transpose() * Base::m_dUq + m_d2Uq * Base::m_sumDotPP +
144 Base::m_uc * m_d2SumW + Base::m_dUc.transpose() * Base::m_dSumW + Base::m_dSumW.transpose() * Base::m_dUc);
145 }
146
147 return Base::m_eCurrentState;
148}
149
150template <class DataPoint, class _NFilter, int DiffType, typename T>
151 requires MLS_SPHERE_FIT_DER_REQUIREMENTS
153 T>::dPotential() const
154{
155 // Compute the 1st order derivative of the scalar field s = uc + x^T ul + x^T x uq
156 // In a centered basis (x=0), we obtain:
157 // the scale derivative: d_t(s)(t,0) = d_t(uc)(t,0)
158 // the spatial derivative: d_x(s)(t,0) = d_x(uc)(t,0) + ul(t,0)
159 ScalarArray result = Base::m_dUc;
160
161 if (Base::isSpaceDer())
162 result.template tail<Dim>() += Base::m_ul;
163
164 return result;
165}
166
167template <class DataPoint, class _NFilter, int DiffType, typename T>
168 requires MLS_SPHERE_FIT_DER_REQUIREMENTS
170 T>::primitiveGradient() const
171{
172 // Compute the 1st order derivative of the scalar field and normalize it
173 VectorType grad = Base::m_dUc.template tail<Dim>().transpose() + Base::m_ul;
174 return grad.normalized();
175}
176
177template <class DataPoint, class _NFilter, int DiffType, typename T>
178 requires MLS_SPHERE_FIT_DER_REQUIREMENTS
180 T>::dNormal() const
181{
182 // Compute the 1st order derivative of the normal, which is the normalized gradient N = d_x(s) / |d_x(s)|
183 // We obtain:
184 // the scale derivative: d_t(N) = (I-N N^T) / |d_x(s)| d2_tx(s)
185 // the spatial derivative: d_x(N) = (I-N N^T) / |d_x(s)| d2_x2(s)
186 // Where in a centered basis (x=0), we have:
187 // d2_tx(s) = d2_tx(uc) + d_t(ul)
188 // d2_x2(s) = d2_x2(uc) + d_x(ul) + d_x(ul)^T + 2 uq I
189 VectorArray result = VectorArray::Zero();
190
191 VectorType grad = Base::m_dUc.template tail<Dim>().transpose() + Base::m_ul;
192 Scalar gradNorm = grad.norm();
193
194 if (Base::isScaleDer())
195 result.col(0) = m_d2Uc.template topRightCorner<1, Dim>().transpose() + Base::m_dUl.col(0);
196
197 if (Base::isSpaceDer())
198 {
199 result.template rightCols<Dim>() = m_d2Uc.template bottomRightCorner<Dim, Dim>().transpose() +
200 Base::m_dUl.template rightCols<Dim>().transpose() +
201 Base::m_dUl.template rightCols<Dim>();
202 result.template rightCols<Dim>().diagonal().array() += Scalar(2.) * Base::m_uq;
203 }
204
205 return result / gradNorm - grad * grad.transpose() / (gradNorm * gradNorm) * result;
206}
Aggregator class used to declare specialized structures using CRTP.
Definition basket.h:294
Extension performing derivation of the mls surface.
typename Base::ScalarArray ScalarArray
Alias to scalar derivatives array.
typename Base::VectorArray VectorArray
Alias to vector derivatives array.
Eigen::Matrix< Scalar, DerDim, DerDim > Matrix
Static squared matrix of scalars with a size adapted to the differentiation type.
typename DataPoint::Scalar Scalar
Alias to scalar type.
typename Base::VectorType VectorType
Alias to vector type.
DiffType
Flags defining which derivatives need to be computed.
Definition enums.h:34
FIT_RESULT
Enum corresponding to the state of a fitting method (and what the finalize function returns)
Definition enums.h:15