Как нарисовать самый большой многоугольник из набора точек

Итак,у меня есть набор точек (x, y), и я хочу иметь возможность рисовать самый большой многоугольник с этими точками в качестве вершин. Я могу использовать патчи.Polygon () в matplotlib, но это просто рисует линии между точками в порядке, который я им даю. Это не делает автоматически то, что я хочу. Например, если вы хотите нарисовать квадрат и отсортировать точки, увеличивая x, а затем увеличивая y, я получу не квадрат, а два соединяющих треугольника. (строка "пересекает")

Так теперь проблема заключается в том, чтобы найти способ отсортировать список точек так, чтобы я "обходил снаружи" полигона при итерации по этому списку.

или, может быть, есть какая-то другая функциональность в Matplotlib, которая может сделать это для меня?

7 ответов


как было предложено все готово простое решение-рассчитать углы от некоторой внутренней точки до всех точек и отсортировать их.

так вот для вас использовать полностью.


Я не знаю Matplotlib, но то, что вам нужно / хотите, это нарисовать выпуклой оболочки точки установить. Подумайте о выпуклой оболочке как эластичной веревке, которую вы размещаете вокруг набора точек. Форма, которую принимает эластичный Канат, - это выпуклая оболочка. Существуют различные алгоритмы вычисления выпуклой оболочки, поэтому проверьте, поддерживает ли Matplotlib какие-либо. Если нет, проверьте эти ссылки для начальной точки о том, как реализовать один.

http://en.wikipedia.org/wiki/Convex_hull

http://en.wikipedia.org/wiki/Convex_hull_algorithms


Если вы уже знаете точки корпуса, то рисование полигона путем подключения этих точек на самом деле довольно легко сделать в Matplotlib, потому что полигоны реализованы в Matplotlib как пути. Я бы начал с библиотек matplotlib.класс пути.

Если вы не знаете точек корпуса, то я согласен с Эльмаром-выпуклая оболочка-это алгоритм, который вы хотите. Я закодировал этот алгоритм в NumPy и построил его в Matplotlib. Мой код был заимствован из отличного рецепта в Поваренной книге SciPy,здесь. Этот рецепт включает реализацию NumPy плюс полный код, необходимый для построения в Matplotlib выпуклой оболочки вокруг заданного набора точек.

кроме того, Matplotlib включает в себя пакет под названием Делонэ, который, как вы уже догадались, для tesselating поверхности с помощью триангуляции Делоне. И, как вы знаете, это связано с выпуклой оболочкой через вороного тесселирование-т. е. границы каждой ячейки Вороного создаются из расчета выпуклой оболочки.


из ваших комментариев к другим ответам, вы, кажется, уже получаем набор точек, определяющих выпуклую оболочку, но они не заказывали. Самый простой способ упорядочить их - взять точку внутри выпуклой оболочки в качестве начала новой системы координат. Затем вы преобразуете (наиболее вероятно) Декартовые координаты ваших точек в полярные координаты относительно этого нового кадра. Если вы упорядочите свои точки относительно их полярной угловой координаты, вы можете нарисовать выпуклую оболочку. Этот действителен только в том случае, если набор ваших точек определил выпуклую (не вогнутую) оболочку.


тогда, как насчет сделать сортировку самостоятельно?

скажем, набор точек выпуклой оболочки хранится в виде списка точки в python и C является какой-то внутренней точкой в вашем наборе точек выпуклой оболочки, вы можете просто подготовить компаратор, как следующий псевдо-код:

def cmpAngle(p1, p2):
    vector1 = p1 - C
    vector2 = p2 - C
    return dotProduct(vector1, vector2)
points.sort(cmp=cmpAngle)

идея в том, чтобы использовать скалярное произведение чтобы выяснить порядок по их относительному вращению.


вот вам и реализация Python выпуклой оболочки (это то, что вы ищете):

http://www.scipy.org/Cookbook/Finding_Convex_Hull


Я использовал scipy.пространственная для такого рода задач. Он имеет специфические функции для построения выпуклых корпусов. См.здесь. Может, это больше огневой мощи, чем ты хотел.