I have a polyline, given as an ordered set of (X,Y) coordinates, that may cross over itself to form one or more loops. From this, I want to extract a polygon that has the loops removed, which will include the intersection points where the line crosses itself. I currently have a crude brute force algorithm that works as follows;
int RemoveLoops(CoordType Points[],int NoPoints)
{
int n = 0; // Start of first line segment
int m = 2; // Offset to n of second line segment
int p = NoPoints;
while (n + m + 1 < p)
{
CoordType Ip; // Intersection point
if (Intersect(Points[n],Points[n+1],Points[n+m],Points[n+m+1],Ip)))
{
Points[n+1] = Ip;
int d = m - 1; // Number of points to delete
for (int i = n + m + 1; i < p; i++)
Points[i - d] = Points[i];
p -= d;
m = 2;
continue; // Restart from intersection point
}
m ++;
if (n + m + 1 >= p) // Reached end of line, change starting segment
{
m = 2; // Reset offset
n++; // Increment starting segment
}
}
return(p); // Return the number of points in the new poly line
}
While I've made a few optimizations to the above, e.g. by counting cumulative angle between successive line segments we know we can't have hit an intersection until we've gone through 360 degrees, the algorithm remains a pretty terrible O(n^2). I know I can do much better than this, e.g. using a set of all intersecting line segments routine as a starting point. Given that the points are already ordered however, I reckon I should be able do better. Note that the above version works in place, and returns the number of remaining points, which is handy but not a requirement.
Any ideas on a good algorithm for the above, O (n log n) or better?