7template <
class DataPo
int,
class _NFilter,
typename T>
8 requires ORIENTED_SPHERE_FIT_REQUIREMENTS
20template <
class DataPo
int,
class _NFilter,
typename T>
21 requires ORIENTED_SPHERE_FIT_REQUIREMENTS
23 const DataPoint& attributes)
25 Base::addLocalNeighbor(w, localQ, attributes);
26 m_sumDotPN += w * attributes.normal().dot(localQ);
27 m_sumDotPP += w * localQ.squaredNorm();
30template <
class DataPo
int,
class _NFilter,
typename T>
31 requires ORIENTED_SPHERE_FIT_REQUIREMENTS
34 PONCA_MULTIARCH_STD_MATH(sqrt);
35 PONCA_MULTIARCH_STD_MATH(max);
36 PONCA_MULTIARCH_STD_MATH(abs);
39 if (Base::finalize() !=
STABLE)
40 return Base::m_eCurrentState;
41 if (Base::getNumNeighbors() < DataPoint::Dim)
43 if (Base::algebraicSphere().isValid())
46 Base::m_eCurrentState = Base::getNumNeighbors() < 2 * DataPoint::Dim ?
UNSTABLE :
STABLE;
49 Scalar epsilon = Eigen::NumTraits<Scalar>::dummy_precision();
53 m_nume = (m_sumDotPN - invSumW * Base::m_sumP.dot(Base::m_sumN));
54 Scalar den1 = invSumW * Base::m_sumP.dot(Base::m_sumP);
55 m_deno = m_sumDotPP - den1;
58 if (abs(m_deno) <= epsilon * max(m_sumDotPP, den1))
60 if (Base::m_ul.isZero(0))
64 Base::m_ul = s * Base::m_ul;
65 Base::m_uc = s * Base::m_uc;
71 Base::m_uq =
Scalar(.5) * m_nume / m_deno;
72 Base::m_ul = (Base::m_sumN - Base::m_sumP * (
Scalar(2.) * Base::m_uq)) * invSumW;
73 Base::m_uc = -invSumW * (Base::m_ul.dot(Base::m_sumP) + m_sumDotPP * Base::m_uq);
76 Base::m_isNormalized =
false;
78 return Base::m_eCurrentState;
81template <
class DataPo
int,
class _NFilter,
int DiffType,
typename T>
82 requires ORIENTED_SPHERE_DER_REQUIREMENTS
89 m_dSumDotPN.setZero();
90 m_dSumDotPP.setZero();
99template <
class DataPo
int,
class _NFilter,
int DiffType,
typename T>
100 requires ORIENTED_SPHERE_DER_REQUIREMENTS
102 const DataPoint& attributes,
105 Base::addLocalNeighbor(w, localQ, attributes, dw);
106 m_dSumN += attributes.normal() * dw;
107 m_dSumDotPN += dw * attributes.normal().dot(localQ);
108 m_dSumDotPP += dw * localQ.squaredNorm();
111template <
class DataPo
int,
class _NFilter,
int DiffType,
typename T>
112 requires ORIENTED_SPHERE_DER_REQUIREMENTS
115 PONCA_MULTIARCH_STD_MATH(sqrt);
123 Scalar nume = Base::m_sumDotPN - invSumW * Base::m_sumP.dot(Base::m_sumN);
124 Scalar deno = Base::m_sumDotPP - invSumW * Base::m_sumP.dot(Base::m_sumP);
129 m_dNume = m_dSumDotPN - invSumW * invSumW *
130 (Base::getWeightSum() * (Base::m_sumN.transpose() * Base::m_dSumP +
131 Base::m_sumP.transpose() * m_dSumN) -
132 Base::m_dSumW * Base::m_sumP.dot(Base::m_sumN));
134 m_dDeno = m_dSumDotPP - invSumW * invSumW *
135 (
Scalar(2.) * Base::getWeightSum() * Base::m_sumP.transpose() * Base::m_dSumP -
136 Base::m_dSumW * Base::m_sumP.dot(Base::m_sumP));
138 m_dUq =
Scalar(.5) * (deno * m_dNume - m_dDeno * nume) / (deno * deno);
142 m_dUl = invSumW * (m_dSumN - Base::m_ul * Base::m_dSumW -
143 Scalar(2.) * (Base::m_dSumP * Base::m_uq + Base::m_sumP * m_dUq));
145 -invSumW * (Base::m_sumP.transpose() * m_dUl + Base::m_sumDotPP * m_dUq +
146 Base::m_ul.transpose() * Base::m_dSumP + Base::m_uq * m_dSumDotPP + Base::m_dSumW * Base::m_uc);
149 return Base::m_eCurrentState;
152template <
class DataPo
int,
class _NFilter,
int DiffType,
typename T>
153 requires ORIENTED_SPHERE_DER_REQUIREMENTS
161 if (Base::isSpaceDer())
162 dgrad.template rightCols<DataPoint::Dim>().diagonal().array() +=
Scalar(2) * Base::m_uq;
163 Scalar norm = Base::m_ul.norm();
164 Scalar norm3 = norm * norm * norm;
165 return dgrad / norm - Base::m_ul * (Base::m_ul.transpose() * dgrad) / norm3;
168template <
class DataPo
int,
class _NFilter,
int DiffType,
typename T>
169 requires ORIENTED_SPHERE_DER_REQUIREMENTS
171 DataPoint, _NFilter,
DiffType, T>::dPotential()
const
174 if (Base::isSpaceDer())
175 dfield.template tail<DataPoint::Dim>() += Base::m_ul;
179template <
class DataPo
int,
class _NFilter,
int DiffType,
typename T>
180 requires ORIENTED_SPHERE_DER_REQUIREMENTS
183 if (Base::isNormalized())
186 PONCA_MULTIARCH_STD_MATH(sqrt);
187 Scalar pn2 = Base::prattNorm2();
193 m_dUc = (m_dUc * pn - Base::m_uc * factor) / pn2;
194 m_dUl = (m_dUl * pn - Base::m_ul * factor) / pn2;
195 m_dUq = (m_dUq * pn - Base::m_uq * factor) / pn2;
197 Base::applyPrattNorm();
[OrientedSphereFit Definition]
typename Base::VectorType VectorType
Alias to vector type.
typename Base::ScalarArray ScalarArray
Alias to scalar derivatives array.
typename DataPoint::Scalar Scalar
Alias to scalar type.
typename Base::VectorArray VectorArray
Alias to vector derivatives array.
Algebraic Sphere fitting procedure on oriented point sets.
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.
FIT_RESULT
Enum corresponding to the state of a fitting method (and what the finalize function returns)
@ UNDEFINED
The fitting is undefined, you can't use it for valid results.
@ CONFLICT_ERROR_FOUND
Multiple classes of the fitting procedure initialize the primitive.
@ STABLE
The fitting is stable and ready to use.
@ UNSTABLE
The fitting is ready to use but it is considered as unstable (if the number of neighbors is low for e...