У меня есть ломаная линия, заданная в виде упорядоченного набора (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) или лучше?