Как нарисовать самый большой многоугольник из набора точек
Итак,у меня есть набор точек (x, y), и я хочу иметь возможность рисовать самый большой многоугольник с этими точками в качестве вершин. Я могу использовать патчи.Polygon () в matplotlib, но это просто рисует линии между точками в порядке, который я им даю. Это не делает автоматически то, что я хочу. Например, если вы хотите нарисовать квадрат и отсортировать точки, увеличивая x, а затем увеличивая y, я получу не квадрат, а два соединяющих треугольника. (строка "пересекает")
Так теперь проблема заключается в том, чтобы найти способ отсортировать список точек так, чтобы я "обходил снаружи" полигона при итерации по этому списку.
или, может быть, есть какая-то другая функциональность в Matplotlib, которая может сделать это для меня?
7 ответов
как было предложено все готово простое решение-рассчитать углы от некоторой внутренней точки до всех точек и отсортировать их.
так вот для вас использовать полностью.
Я не знаю Matplotlib, но то, что вам нужно / хотите, это нарисовать выпуклой оболочки точки установить. Подумайте о выпуклой оболочке как эластичной веревке, которую вы размещаете вокруг набора точек. Форма, которую принимает эластичный Канат, - это выпуклая оболочка. Существуют различные алгоритмы вычисления выпуклой оболочки, поэтому проверьте, поддерживает ли Matplotlib какие-либо. Если нет, проверьте эти ссылки для начальной точки о том, как реализовать один.
Если вы уже знаете точки корпуса, то рисование полигона путем подключения этих точек на самом деле довольно легко сделать в 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)
идея в том, чтобы использовать скалярное произведение чтобы выяснить порядок по их относительному вращению.
Я использовал scipy.пространственная для такого рода задач. Он имеет специфические функции для построения выпуклых корпусов. См.здесь. Может, это больше огневой мощи, чем ты хотел.