I второе предложение groovingandi попробовать все полигоны; вам просто нужно убедиться в правильности полигона (без самопересечений и т. д.).
Теперь, если вы хотите работать с большим количеством точек ... Как указал MatlabDoug, выпуклый корпус - это хорошее место для начала. Обратите внимание, что выпуклая оболочка дает многоугольник, площадь которого максимально возможная. Проблема, конечно, в том, что внутри корпуса могут быть точки, которые не являются частью многоугольника. Я предлагаю следующий жадный алгоритм, но я не уверен, гарантирует ли он максимальный полигон области.
Основная идея состоит в том, чтобы начать с выпуклого корпуса в качестве конечного полигона кандидата и вырезать треугольники, соответствующие неиспользуемым точкам, пока все точки не будут принадлежать окончательному многоугольнику. На каждом этапе удаляется наименьший возможный треугольник.
Given: Points P = {p1, ... pN}, convex hull H = {h1, ..., hM}
where each h is a point that lies on the convex hull.
H is a subset of P, and it is also ordered such that adjacent
points in the list of H are edges of the convex hull, and the
first and last points form an edge.
Let Q = H
while(Q.size < P.size)
% For each point, compute minimum area triangle
T = empty heap of triangles with value of their area
For each P not in Q
For each edge E of Q
If triangle formed by P and E does not contain any other point
Add triangle(P,E) with value area(triangle(P,E))
% Modify the current polygon Q to carve out the triangle
Let t=(P,E) be the element of T with minimum area
Find the ordered pair of points that form the edge E within Q
(denote them Pa and Pb)
Replace the pair (Pa,Pb) with (Pa,E,Pb)
Теперь, на практике вам не нужна куча для T
, просто добавить данные в четыре списков: один для P, один для Па, один для Pb, и один для области. Чтобы проверить, находится ли точка в треугольнике, вам нужно только проверить каждую точку на линии, образующие стороны треугольника, и вам нужно только проверить точки, которые еще не были в Q. Наконец, чтобы вычислить площадь конечного многоугольника, вы можете триангулировать его (например, с помощью функции delaunay
и суммировать области каждого треугольника в триангуляции), или вы можете найти область выпуклого корпуса и вычесть области треугольников по мере их вырезания.
Опять же, я не знаю, гарантирован ли этот жадный алгоритм найти максимальный многоугольник области, но я думаю, что он должен работать большую часть времени и, тем не менее, интересен.
Я не думаю, что алгоритм гарантирует вам максимальный многоугольник области, так как результат зависит от порядка оставшихся точек. Но это уменьшает, по крайней мере, количество перестановок, которые вы должны проверить ... – groovingandi
@groovingandi Как результат зависит от порядка оставшихся точек? На каждом этапе вы учитываете все остальные точки и выбираете лучший из них. –
@ Victor Lui: А теперь я вижу ... В первый раз, когда я прочитал ваш алгоритм, я почему-то упустил из виду, что вы все время считаете все остальное, прежде чем решать, какой из них следует включить дальше. Тогда, конечно, это не зависит от порядка остальных точек. Я попытался найти контрпример, где ваш алгоритм не работает, но до сих пор не удалось ... – groovingandi