10template <
class DataPo
int,
class _NFilter,
typename T>
11 requires COVARIANCE_PLANE_FIT_REQUIREMENTS
12FIT_RESULT CovariancePlaneFitImpl<DataPoint, _NFilter, T>::finalize()
14 if (Base::finalize() == STABLE)
16 if (Base::plane().isValid())
18 Base::setPlane(Base::m_solver.eigenvectors().col(0), Base::barycenterLocal());
21 return Base::m_eCurrentState;
24template <
class DataPo
int,
class _NFilter,
typename T>
25 requires COVARIANCE_PLANE_FIT_REQUIREMENTS
26typename CovariancePlaneFitImpl<DataPoint, _NFilter, T>::VectorType CovariancePlaneFitImpl<
27 DataPoint, _NFilter, T>::worldToTangentPlane(
const VectorType& _q,
bool _isPositionVector)
const
29 return Base::m_solver.eigenvectors().transpose() *
30 Base::getNeighborFrame().convertToLocalBasis(_q, _isPositionVector);
33template <
class DataPo
int,
class _NFilter,
typename T>
34 requires COVARIANCE_PLANE_FIT_REQUIREMENTS
35typename CovariancePlaneFitImpl<DataPoint, _NFilter, T>::VectorType CovariancePlaneFitImpl<
36 DataPoint, _NFilter, T>::tangentPlaneToWorld(
const VectorType& _lq,
bool _isPositionVector)
const
38 return Base::getNeighborFrame().convertToGlobalBasis(Base::m_solver.eigenvectors().transpose().inverse() * _lq,
42template <
class DataPo
int,
class _NFilter,
int DiffType,
typename T>
43 requires COVARIANCE_PLANE_DER_REQUIREMENTS
44FIT_RESULT CovariancePlaneDerImpl<DataPoint, _NFilter, DiffType, T>::finalize()
46 PONCA_MULTIARCH_CU_STD_FUNC(numeric_limits);
52 VectorType
barycenter = Base::barycenterLocal();
53 VectorArray dBarycenter = Base::barycenterDerivatives();
56 Scalar epsilon = Scalar(2) * Eigen::NumTraits<Scalar>::epsilon();
57 Scalar consider_as_zero = Scalar(2) * numeric_limits<Scalar>::denorm_min();
61 Eigen::Matrix<Scalar, 2, 1> shifted_eivals =
62 Base::m_solver.eigenvalues().template tail<2>().array() - Base::m_solver.eigenvalues()(0);
63 if (shifted_eivals(0) < consider_as_zero || shifted_eivals(0) < epsilon * shifted_eivals(1))
64 shifted_eivals(0) = 0;
65 if (shifted_eivals(1) < consider_as_zero)
66 shifted_eivals(1) = 0;
68 for (
int k = 0; k < Base::NbDerivatives; ++k)
70 VectorType normal = Base::primitiveGradient();
79 Eigen::Matrix<Scalar, 2, 1> z =
80 -Base::m_solver.eigenvectors().template rightCols<2>().transpose() * (Base::m_dCov[k] * normal);
81 if (shifted_eivals(0) > 0)
82 z(0) /= shifted_eivals(0);
83 if (shifted_eivals(1) > 0)
84 z(1) /= shifted_eivals(1);
85 m_dNormal.col(k) = Base::m_solver.eigenvectors().template rightCols<2>() * z;
87 VectorType dDiff = dBarycenter.col(k);
88 if (k > 0 || !Base::isScaleDer())
89 dDiff(Base::isScaleDer() ? k - 1 : k) += 1;
90 m_dDist(k) = m_dNormal.col(k).dot(barycenter) + normal.dot(dDiff);
94 return Base::m_eCurrentState;
Ponca::MeanPosition T barycenter() const
where are all the point samples in 's neighborhood
FIT_RESULT
Enum corresponding to the state of a fitting method (and what the finalize function returns).
@ CONFLICT_ERROR_FOUND
Multiple classes of the fitting procedure initialize the primitive.