Есть ли эффективный алгоритм для создания 2D вогнутого корпуса?

Имея набор (2D) точек из файла ГИС (карта города), мне нужно сгенерировать многоугольник, определяющий «контур» этой карты (ее границу). Его входными параметрами будут набор точек и «максимальная длина кромки». Затем он выведет соответствующий (возможно, невыпуклый) многоугольник.

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


person Fabio Ceconello    schedule 17.09.2008    source источник
comment
Вы говорите, что у вас есть файл ГИС - вы не используете картографическое приложение / программное обеспечение ГИС? Я знаю, что сервер ArcGIS с радостью использует любое количество точек и построит карту, наложенную на получившийся многоугольник.   -  person Ian    schedule 17.09.2008
comment
Да, у меня есть файл ГИС, но мне нужно написать алгоритм (возможно, на C или C ++), он должен быть помещен в уже существующую программу, и для этого не следует использовать внешние инструменты (например, ArcGIS), это должен быть самодостаточным.   -  person Fabio Ceconello    schedule 17.09.2008
comment
На самом деле, я не думаю, что у ArcGIS есть встроенный алгоритм, позволяющий делать то, что он хочет. ArcGIS может создавать выпуклые оболочки, но вогнутые намного сложнее.   -  person Chris Upchurch    schedule 17.09.2008
comment
Не могли бы вы более точно определить вашу проблему? :) С 5 баллами: 4 угла квадрата и его центр. Какой была бы ваша граница? Если ваша максимальная длина края допускает центр, совершенно произвольно, в какой из 4 краев квадрата вы должны «согнуть», чтобы включить среднюю точку.   -  person Luke Halliwell    schedule 17.09.2008
comment
В приведенном вами примере ответом всегда будет квадрат. Как правило, учитывая каждую точку и расстояния до двух ближайших других точек, вы можете предположить, что максимальная длина ребра никогда не будет меньше второй, поэтому никогда не должно быть «осиротевших» точек.   -  person Fabio Ceconello    schedule 18.09.2008
comment
@Fabio Ceconello - Вы когда-нибудь реализовывали алгоритм для этого?   -  person stevehipwell    schedule 29.01.2010
comment
Да, именно так, как я упомянул в вопросе (с треугольниками Делоне). Позже я немного поработал над концепцией альфа-форм, указанной ниже nsanders, но прежде, чем я заставил ее работать, приоритет проблемы был понижен, и я перешел к другой.   -  person Fabio Ceconello    schedule 07.02.2010
comment
Делоне имеет правильную сложность (O (n log n)). Я сомневаюсь, что асимптотически вы сможете добиться большего.   -  person Alexandre C.    schedule 28.08.2011
comment
Вы приняли ответ всего через 9 лет!   -  person peterh    schedule 24.03.2017
comment
@peterh Я сразу принял ответ, но позже по какой-то причине он был удален, поэтому, когда я заметил, что принял другой ответ, это было бы моим вторым лучшим ответом.   -  person Fabio Ceconello    schedule 24.03.2017
comment
@peterh Я придерживаюсь мнения, что нельзя принимать ответ, пока кто-то не предоставит правильный код. Если Фабио опубликует хотя бы фрагмент своего кода, я бы поддержал его за любой из этих ответов и проголосовал против всех остальных, чтобы переместить его вверх по списку.   -  person Nathan    schedule 01.02.2019
comment
Кроме того, я смущен вашим решением. Вам приходилось вручную удалять края или ваше решение было автоматическим? (т.е. код решил все от начала до конца) По крайней мере, похоже, что вам нужно было выбрать максимальную длину края методом проб и ошибок, а не каким-либо алгоритмическим способом.   -  person Nathan    schedule 01.02.2019
comment
@peterh думает об этом, я думаю, ты прав, я оставлю это без принятого ответа. Что касается фрагмента, мне придется вернуться к некоторому старому коду, и я даже не помню, насколько маленьким (или большим) будет такой фрагмент и сколько мне придется отредактировать, чтобы сделать его понятным. Если есть возможность, выложу.   -  person Fabio Ceconello    schedule 01.02.2019
comment
@frank Это не было вручную, это было частью автоматизированного инструмента для обработки карт для приложения GPS-навигации. В моем конкретном случае это было действительно произвольно - точки были углами улиц, а получившийся многоугольник был контуром города. Я использовал произвольное значение, которое дало бы мне достаточно подробный многоугольник, который не был бы слишком тяжелым для рендеринга. Я думаю, что так и должно быть, вы должны определить максимальную длину в соответствии с потребностями вашего приложения - я не понимаю, как вы могли бы заранее рассчитать ее автоматически.   -  person Fabio Ceconello    schedule 01.02.2019
comment
@FabioCeconello Нет! Если ответ отвечает на вопрос, примите его! Я был так счастлив, что нашел самый длинный принятый вопрос, я не хотел, чтобы вы его отклонили!   -  person peterh    schedule 02.02.2019


Ответы (10)


В этой статье обсуждается Эффективное создание простых многоугольников для описания формы набор точек на плоскости и предоставляет алгоритм. Существует также Java-апплет, использующий тот же алгоритм, здесь.

person Amirali    schedule 15.02.2014
comment
Ссылка мертва. Исходный код Java находится по адресу ambientspatial.net/ddo/?p=143 - person Ian; 29.09.2016

Один из бывших студентов нашей лаборатории использовал некоторые применимые методы для своей кандидатской диссертации. Я считаю, что одна из них называется «альфа-формы» и упоминается в следующей статье:

http://www.cis.rit.edu/people/faculty/kerekes/pdfs/AIPR_2007_Gurram.pdf

В этой статье даются некоторые дальнейшие ссылки, за которыми вы можете следовать.

person nsanders    schedule 17.09.2008
comment
Альфа-формы основаны на триангуляции Делоне, поэтому обязательно потребуется одно вычисление тринагуляции Делоне. - person balint.miklos; 10.09.2009
comment
Мне кажется, что альфа-формы - это всего лишь концепция. - person Gigamegs; 24.09.2013

Ребята, здесь утверждают, что они разработали подход ближайших соседей к определению вогнутости корпуса. набора точек, который ведет себя «почти линейно в зависимости от количества точек». К сожалению, их газета, кажется, очень хорошо охраняется, и вам придется спросить их за это.

Вот хороший набор ссылок это включает в себя вышеперечисленное и может привести вас к поиску лучшего подхода.

person Vinko Vrsalovic    schedule 17.09.2008
comment
Похоже, это и есть статья, о которой идет речь: repositorium.sdum. uminho.pt/bitstream/1822/6429/1/ Идея исключительно умная и простая - это просто прямая модификация техники сканирования Грэма для выпуклых нулей, насколько я понимаю. Нет необходимости искать триангуляцию Делоне и т. Д. - person Zach Conn; 29.03.2014
comment
Упомянутое название статьи - Вогнутый корпус: подход k-ближайших соседей для вычисления области, занимаемой набором точек. Он доступен здесь: repositorium.sdum.uminho.pt/handle/1822/6429 - person deshu; 24.12.2019

Ответ может быть интересен кому-то еще: можно применить вариант алгоритма маршевого квадрата, применяемый (1) в вогнутом корпусе и (2) затем (например, 3) на разных <сильных > Масштабы, которые мои зависят от средней плотности точек. Масштабы должны быть кратными друг другу, например, вы создаете сетку, которую можете использовать для эффективной выборки. Это позволяет быстро находить пустые сэмплы = квадраты, сэмплы, полностью попадающие в «кластер / облако» точек, и те, которые находятся между ними. Последнюю категорию затем можно использовать для легкого определения ломаной линии, представляющей часть вогнутой части корпуса.

В этом подходе все линейно, триангуляция не требуется, он не использует альфа-формы и отличается от коммерческого / запатентованного предложения, описанного здесь (http://www.concavehull.com/)

person monnoo    schedule 29.01.2012

Быстрое приближенное решение (также полезно для выпуклой оболочки) - найти северные и южные границы для каждого небольшого элемента с востока на запад.

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

Также стоит заранее сделать быструю проверку на очень длинные тонкие формы и решить, следует ли использовать NS или Ew.

person Martin Beckett    schedule 17.09.2008

Простое решение - обойти край многоугольника. Учитывая текущее ребро на границе, соединяющей точки P0 и P1, следующей точкой на границе P2 будет точка с наименьшим возможным A, где

H01 = bearing from P0 to P1
H12 = bearing from P1 to P2
A = fmod( H12-H01+360, 360 )
|P2-P1| <= MaxEdgeLength

Затем вы устанавливаете

P0 <- P1
P1 <- P2

и повторяйте, пока не вернетесь к тому, с чего начали.

Это все еще O (N ^ 2), поэтому вам нужно немного отсортировать свой список точек. Вы можете ограничить набор точек, которые необходимо учитывать на каждой итерации, если вы отсортируете точки, скажем, по их направлению от центроида города.

person Community    schedule 17.09.2008

Хороший вопрос! Я вообще этого не пробовал, но первым делом я попробую использовать следующий итеративный метод:

  1. Создайте набор N («не содержится») и добавьте все точки в вашем наборе к N.
  2. Выберите 3 точки из N случайным образом, чтобы сформировать начальный многоугольник P. Удалите их из N.
  3. Используйте алгоритм точки в многоугольнике и посмотрите на точки в N. Для каждой точки в N , если теперь он содержится в P, удалите его из N. Как только вы найдете точку в N, которая все еще не содержится в P, переходите к шагу 4. Если N становится пустым, все готово.
  4. Назовите найденную точку A. Найдите линию в P, ближайшую к A, и добавьте A в ее середину.
  5. Вернитесь к шагу 3

Я думаю, что это будет работать, если оно работает достаточно хорошо - может помочь хорошая эвристика для ваших начальных 3 баллов.

Удачи!

person Rob Dickerson    schedule 17.09.2008

Вы можете сделать это в QGIS с помощью этого плагина; https://github.com/detlevn/QGIS-ConcaveHull-Plugin

В зависимости от того, как вам нужно взаимодействовать с вашими данными, возможно, стоит проверить, как это было сделано здесь.

person Cameron    schedule 18.02.2016

Как широко распространенная ссылка, PostGIS начинается с выпуклой оболочки, а затем прогибается, вы можете увидеть это здесь.

https://github.com/postgis/postgis/blob/380583da73227ca1a52da0e0b3413b92ae69af9d/postgis/postgis.sql.in#L5819

person Evan Carroll    schedule 29.11.2017

Интерактивный SDK Bing Maps V8 имеет опцию вогнутого корпуса в расширенных операциях с фигурами.

https://www.bing.com/mapspreview/sdkrelease/mapcontrol/isdk/advancedshapeoperations?toWww=1&redig=D53FACBB1A00423195C53D841EA0D14E#JS

В ArcGIS 10.5.1 дополнительный модуль 3D Analyst имеет инструмент Минимальный ограничивающий объем с геометрическими типами вогнутой оболочки, сферы, оболочки или выпуклой оболочки. Его можно использовать на любом уровне лицензии.

Здесь есть алгоритм вогнутой оболочки: https://github.com/mapbox/concaveman

person Jaybird64    schedule 13.02.2018