Ponca  aa50bfdf187919869239c5b44b748842569114c1
Point Cloud Analysis library
Loading...
Searching...
No Matches
sphereFit.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, typename T>
9void
11{
12 Base::init(_evalPos);
13 m_matA.setZero();
14}
15
16template < class DataPoint, class _WFunctor, typename T>
17bool
19 const VectorType &localQ,
20 const DataPoint &attributes)
21{
22 if( Base::addLocalNeighbor(w, localQ, attributes) ) {
23 VectorA a;
24#ifdef __CUDACC__
25 a(0) = 1;
26 a.template segment<DataPoint::Dim>(1) = localQ;
27 a(DataPoint::Dim+1) = localQ.squaredNorm();
28#else
29 a << 1, localQ, localQ.squaredNorm();
30#endif
31 m_matA += w * a * a.transpose();
32 return true;
33 }
34
35 return false;
36}
37
38
39template < class DataPoint, class _WFunctor, typename T>
42{
43 // Compute status
44 if(Base::finalize() != STABLE)
45 return Base::m_eCurrentState;
46 if(Base::getNumNeighbors() < DataPoint::Dim)
47 return Base::m_eCurrentState = UNDEFINED;
48 if (Base::algebraicSphere().isValid())
49 Base::m_eCurrentState = CONFLICT_ERROR_FOUND;
50 else
51 Base::m_eCurrentState = Base::getNumNeighbors() < 2*DataPoint::Dim ? UNSTABLE : STABLE;
52
53 MatrixA matC;
54 matC.setIdentity();
55 matC.template topRightCorner<1,1>() << -2;
56 matC.template bottomLeftCorner<1,1>() << -2;
57 matC.template topLeftCorner<1,1>() << 0;
58 matC.template bottomRightCorner<1,1>() << 0;
59
60 MatrixA invCpratt;
61 invCpratt.setIdentity();
62 invCpratt.template topRightCorner<1,1>() << -0.5;
63 invCpratt.template bottomLeftCorner<1,1>() << -0.5;
64 invCpratt.template topLeftCorner<1,1>() << 0;
65 invCpratt.template bottomRightCorner<1,1>() << 0;
66
67 // Remarks:
68 // A and C are symmetric so all eigenvalues and eigenvectors are real
69 // we look for the minimal positive eigenvalue (eigenvalues may be negative)
70 // C^{-1}A is not symmetric
71 // calling Eigen::GeneralizedEigenSolver on (A,C) and Eigen::EigenSolver on C^{-1}A is equivalent
72 // C is not positive definite so Eigen::GeneralizedSelfAdjointEigenSolver cannot be used
73#ifdef __CUDACC__
74 m_solver.computeDirect(invCpratt * m_matA);
75#else
76 m_solver.compute(invCpratt * m_matA);
77#endif
78 VectorA eivals = m_solver.eigenvalues().real();
79 int minId = -1;
80 for(int i=0 ; i<DataPoint::Dim+2 ; ++i)
81 {
82 Scalar ev = eivals(i);
83 if((ev>0) && (minId==-1 || ev<eivals(minId)))
84 minId = i;
85 }
86
87 //mLambda = eivals(minId);
88 VectorA vecU = m_solver.eigenvectors().col(minId).real();
89 Base::m_uq = vecU[1+DataPoint::Dim];
90 Base::m_ul = vecU.template segment<DataPoint::Dim>(1);
91 Base::m_uc = vecU[0];
92
93 Base::m_isNormalized = false;
94
95 return Base::m_eCurrentState;
96}
Algebraic Sphere fitting procedure on point set without normals.
Definition: sphereFit.h:57
typename DataPoint::Scalar Scalar
Alias to scalar type.
Definition: sphereFit.h:58
typename Base::VectorType VectorType
Alias to vector type.
Definition: sphereFit.h:58
FIT_RESULT
Enum corresponding to the state of a fitting method (and what the finalize function returns)
Definition: enums.h:15
@ UNDEFINED
The fitting is undefined, you can't use it for valid results.
Definition: enums.h:22
@ CONFLICT_ERROR_FOUND
Multiple classes of the fitting procedure initialize the primitive.
Definition: enums.h:27
@ STABLE
The fitting is stable and ready to use.
Definition: enums.h:17
@ UNSTABLE
The fitting is ready to use but it is considered as unstable (if the number of neighbors is low for e...
Definition: enums.h:20