我有一条折线,给定为一个有序的(X,Y)坐标集合,可能交叉形成一个或多个环。从中,我想提取一个多边形,将环去除,其中包括线段相交的点。我目前有一个粗糙的暴力算法,其工作原理如下:
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
}
尽管我对上述内容进行了一些优化,例如通过计算相邻线段之间累积角度,我们知道在经过360度之前,我们不可能撞到交点,但这个算法仍然是一个相当糟糕的O(n^2)。我知道我可以做得比这好得多,例如使用所有相交线段的集合例程作为起点。然而,考虑到点已经被排序,我认为我应该能够做得更好。请注意,上述版本在原地工作,并返回剩余点的数量,这很方便,但不是必需的。
对于上述内容,有没有好的O(n log n)或更好的算法?