I have a point cloud and I want to sort points clockwise.
I am trying to use this code:
public static List<Point3D> OrderPointsLinearPath(List<Point3D> points)
{
if (points == null || points.Count <= 1)
return points;
// Create a list to store the ordered points
var orderedPoints = new List<Point3D>();
var remainingPoints = new HashSet<Point3D>(points);
// Start with the leftmost point
var currentPoint = remainingPoints.OrderBy(p => p.X).First();
orderedPoints.Add(currentPoint);
remainingPoints.Remove(currentPoint);
while (remainingPoints.Count > 0)
{
// Find the closest point to the current point
var nearestPoint = remainingPoints
.OrderBy(p => currentPoint.DistanceTo(p))
.First();
orderedPoints.Add(nearestPoint);
currentPoint = nearestPoint;
remainingPoints.Remove(nearestPoint);
}
return orderedPoints;
}
The problem is on the top left side of the image, there is an orphelin point left as shown on the second image.
I understand why. If we imagine that I am starting from the first point on the image and take the nearest to continue, when I am on the 10th point, the 12th point is closer than the 11th one.
I tried many thing like taking the centroid and ordering by
public class Ordered3DPoint
{
public Point3D centroid;
public Point3D ro;
public double AngleToCentroid;
public Point3D RefPoint;
public Ordered3DPoint(Point3D centroid, Point3D ro)
{
this.centroid = centroid;
this.ro = ro;
var delta = (ro - centroid);
AngleToCentroid = Math.Atan2(-delta.Y, delta.X);
RefPoint = ro;
}
}
var cX = points.Sum(ro => ro.X) / points.Count;
var cY = points.Min(ro => ro.Y);
var cZ = points.Sum(ro => ro.Z) / points.Count;
var centroid = new Point3D(cX, cY, cZ);
var orderedPoints = points.Select(ro => new Ordered3DPoint(points.First(), ro)).ToList();
points = orderedPoints.OrderByDescending(ro => ro.AngleToCentroid).Select(ro => ro.RefPoint).ToList();
return points;
It doesn't work because of the forms bent structure.

