I am trying to triangulate a set of points using a very simple approach where a base vertex is chosen, and then every other vertex is joined to its neighbouring vertex and then back to the base vertex, to create a triangle-fan structure, which creates a solid surface.
The problem with this approach is that in order to triangulate it there is a lot of iterating, and for each triangulation point, it must iterate over the entire list again to find its nearest CW point which is very slow, but works.
for (int i = 1; i < triangulationPoints.Count; i++)
{
//this method iterates over available which is a copy of triangulationPoints
//and finds the closest vertex with no backtracking
Vector3 vertex = findClosestVertex(currentVertex, available, ordered);
//...
available.Remove(vertex);
}
Now I'm looking to speed up the algorithm so I get the same effect, but faster.
I implemented a binary insert function that sort each point based on distance from the base vertex as it is inserted into the triangulationPoint list which works nicely and is fast, but produces incorrect results as it doesn't take into account the next CW vertex, but any vertex.
Does anyone have any suggestions as to how I can speed this up, or perhaps another triangulation algorithm that is relatively easy to implement which would achieve fast speeds?
Edit I have tried Unity's triangulator and that produces results that are worse than my attempt. I have also tried a third-party triangulator (https://github.com/CiaccoDavide/Unity-UI-Polygon) and this seems to be exactly what I need, however it only draws on the UI and not in world space.
An attempt at implementing DMGregory's explanation
Quaternion toPlaneSpace = Quaternion.Inverse(Quaternion.LookRotation(cutter.normal));
centroidPosition = centroidPosition / sharedIntersectionPoints.Count;
foreach (Vector3 v in sharedIntersectionPoints)
{
Vector3 offset = toPlaneSpace * (v - centroidPosition);
IntersectionPoint ip = new IntersectionPoint(v, Mathf.Atan2(offset.y, offset.x));
int index = binaryInsertAngle(new IntersectionPoint(v, Mathf.Atan2(offset.y, offset.x)), 0, points.Count);
if (index > orderedTriangulationPoints.Count)
{
orderedTriangulationPoints.Add(ip.point);
points.Add(ip);
}
else
{
orderedTriangulationPoints.Insert(index, ip.point);
points.Insert(index, ip);
}
}
Both the new ordered list and the old ordered list are the same size so it should be stepping over the vertices correctly without missing any.