Как вы видите на рисунке, вопрос заключается в следующем:
Как найти прямоугольник минимальной площади (MAR), расположенный в заданных точках?
и подтверждающий вопрос:
Есть ли аналитическое решение проблемы?
(Развитие вопроса будет состоять в том, чтобы поместить прямоугольник (3D) в кластер точек в трехмерном облаке точек.)
В качестве первого этапа я предлагаю найти выпуклую оболочку для точек, которые решают проблему (удаляя эти точки, которые не участвуют в решении) для: подгонки MAR к многоугольнику. Требуемый метод предоставит X ( центр прямоугольника ), D ( два измерения ) и A ( угол ).
Мое предложение для решения:
- Найти центр тяжести многоугольника (см. Поиск центра геометрии объекта? )
- [S] Установите простой подогнанный прямоугольник, т. Е. Параллельно осям X и Y
- Вы можете использовать
minmax
функцию для X и Y заданных точек (например, вершин многоугольника)
- Вы можете использовать
- Сохраните область подогнанного прямоугольника
- Поворот многоугольника вокруг центроида, например, на 1 градус
- Повторите от [S] до полного вращения
- Сообщите угол минимальной площади как результат
Это выглядит многообещающе, однако существуют следующие проблемы:
- выбор хорошего разрешения для изменения угла может быть сложной задачей,
- высокая стоимость вычислений,
- решение не аналитическое, а экспериментальное.
В дополнение к отличному решению @ julien, здесь есть рабочая реализация
R
, которая может служить псевдокодом для руководства любой конкретной реализацией ГИС (илиR
, конечно, применяться напрямую ). Ввод представляет собой массив координат точки. Выход (значениеmbr
) представляет собой массив вершин минимального ограничивающего прямоугольника (с повторением первой, чтобы закрыть его). Обратите внимание на полное отсутствие каких-либо тригонометрических расчетов.Вот пример его использования:
Время ограничено скоростью алгоритма выпуклой оболочки, потому что количество вершин в корпусе почти всегда намного меньше, чем общее. Большинство алгоритмов выпуклой оболочки асимптотически O (n * log (n)) для n точек: вы можете вычислить почти так же быстро, как вы можете прочитать координаты.
источник
Я сам реализовал это и опубликовал свой ответ в StackOverflow , но я решил оставить свою версию здесь для просмотра другими:
Вот четыре различных примера этого в действии. Для каждого примера я сгенерировал 4 случайных точки и нашел ограничивающий прямоугольник.
Это сравнительно быстро для этих образцов на 4 балла:
источник
points = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
, и на выходеarray([[1.00000000e+00, 6.12323400e-17], [0.00000000e+00, 0.00000000e+00], [6.12323400e-17, 1.00000000e+00], [1.00000000e+00, 1.00000000e+00]])
получился квадрат единицы (включая некоторые ошибки округления с плавающей запятой). Примечание: квадрат - это просто прямоугольник с равными сторонами, поэтому я предполагаю, что если он может обрабатывать квадрат, он обобщается на все прямоугольники.В Whitebox GAT есть инструмент ( http://www.uoguelph.ca/~hydrogeo/Whitebox/ ), который называется Minimum Bounding Box для решения именно этой проблемы. Там также есть инструмент с минимальным выпуклым корпусом. Некоторые из инструментов в наборе инструментов Patch Shape, например, ориентация и удлинение патча, основаны на поиске минимальной ограничительной рамки.
источник
Я наткнулся на эту тему, когда искал решение Python для ограничивающего прямоугольника с минимальной площадью.
Вот моя реализация , результаты которой были проверены с помощью Matlab.
Тестовый код включен для простых полигонов, и я использую его, чтобы найти двухмерную минимальную ограничивающую рамку и направления осей для 3D PointCloud.
источник
Спасибо, ответ @ whuber. Это отличное решение, но медленное для большого облака точек. Я обнаружил, что
convhulln
функция в пакете Rgeometry
работает намного быстрее (138 с против 0,03 с для 200000 баллов). Я вставил здесь свои коды для всех, кто заинтересован в более быстром решении.Два метода получают один и тот же ответ (пример для 2000 баллов):
источник
Я просто рекомендую встроенную функцию OpenCV
minAreaRect
, которая находит повернутый прямоугольник минимальной области, содержащей входной набор 2D-точек. Чтобы увидеть, как использовать эту функцию, можно обратиться к этому руководству .источник