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