@@ -216,6 +216,59 @@ namespace diffCheck::geometry
216216 this ->Normals .push_back (normal);
217217 }
218218
219+ std::vector<Eigen::Vector3d> DFPointCloud::GetPrincipalAxes (int nComponents)
220+ {
221+ std::vector<Eigen::Vector3d> principalAxes;
222+
223+ if (! this ->HasNormals ())
224+ {
225+ DIFFCHECK_WARN (" The point cloud has no normals. Normals will be estimated with knn = 20." );
226+ this ->EstimateNormals (true , 20 );
227+ }
228+
229+ // Convert normals to Eigen matrix
230+ Eigen::Matrix<double , 3 , Eigen::Dynamic> normalMatrix (3 , this ->Normals .size ());
231+ for (size_t i = 0 ; i < this ->Normals .size (); ++i)
232+ {
233+ normalMatrix.col (i) = this ->Normals [i].cast <double >();
234+ }
235+
236+ cilantro::KMeans<double , 3 > kmeans (normalMatrix);
237+ kmeans.cluster (nComponents);
238+
239+ const auto & centroids = kmeans.getClusterCentroids ();
240+ const auto & assignments = kmeans.getPointToClusterIndexMap ();
241+
242+ std::vector<std::pair<int , Eigen::Vector3d>> clusters (nComponents);
243+ for (size_t i = 0 ; i < nComponents; ++i)
244+ {
245+ clusters[i] = {i, centroids.col (i)};
246+ }
247+ std::sort (clusters.begin (), clusters.end (), [](const auto & a, const auto & b)
248+ {
249+ return a.second .norm () < b.second .norm ();
250+ });
251+
252+ std::vector<std::pair<int , Eigen::Vector3d>> sortedClusters (nComponents);
253+ std::vector<int > clusterSizes (nComponents, 0 );
254+
255+ std::vector<std::pair<int , Eigen::Vector3d>> sortedClustersBySize (nComponents);
256+ for (size_t i = 0 ; i < nComponents; ++i)
257+ {
258+ sortedClustersBySize[i] = {clusterSizes[i], centroids.col (i)};
259+ }
260+ std::sort (sortedClustersBySize.begin (), sortedClustersBySize.end (), [](const auto & a, const auto & b)
261+ {
262+ return a.first > b.first ;
263+ });
264+
265+ for (size_t i = 0 ; i < nComponents; ++i)
266+ {
267+ principalAxes.push_back (sortedClustersBySize[i].second );
268+ }
269+ return principalAxes;
270+ }
271+
219272 void DFPointCloud::UniformDownsample (int everyKPoints)
220273 {
221274 auto O3DPointCloud = this ->Cvt2O3DPointCloud ();
0 commit comments