Слияние и разбиение перекрывающихся прямоугольников для получения неперекрывающихся прямоугольников
Я ищу следующий алгоритм:
Задан набор возможно перекрывающихся прямоугольников (все из которых "не вращаются", могут быть равномерно представлены как (левый,верхний,правый,нижний) кортежи и т. д...), он возвращает минимальный набор (не вращающихся) неперекрывающихся прямоугольников, которые занимают одну и ту же площадь.
На первый взгляд это кажется достаточно простым, но доказательства, чтобы быть сложным (по крайней мере, чтобы быть сделано эффективно).
Существуют ли известные методы для это / идеи / указатели?
Интересны также методы для не обязательно минимальных, но эвристически малых множеств, так же как и методы, которые производят любое допустимое выходное множество вообще.
2 ответа:
Что-то, основанное на алгоритме линейной развертки, будет работать, я думаю:
- отсортируйте все координаты ваших прямоугольников min и max
x
в массив, как события" start-rectangle "и" end-rectangle "- Шаг через массив, добавляя каждый новый встреченный прямоугольник (start-event) в текущий набор
- одновременно поддерживайте набор "неперекрывающихся прямоугольников", который будет вашим выходным набором
- каждый раз, когда вы сталкиваетесь с новым прямоугольником, вы можете проверить, является ли он полностью содержится уже в текущем / выходном наборе (достаточно простого сравнения
y
-координат)- Если это не так, добавьте новый прямоугольник в свой выходной набор, с
y
-координатами, установленными на ту часть нового прямоугольника, которая еще не покрыта.- каждый раз, когда вы попадаете в событие окончания прямоугольника, остановите все прямоугольники в вашем выходном наборе, которые больше ничего не покрывают.
Я не совсем уверен, что это охватывает все, но я думаю, что с некоторыми настройками это должно быть сделай свою работу. Или, по крайней мере, дать вам несколько идей... :)
Итак, если бы я попытался сделать это, первое, что я сделал бы, - это придумал бы единое сеточное пространство. Найдите все уникальные координаты x и y и создайте сопоставление с индексным пространством. Таким образом, если у вас есть значения x { -1, 1.5, 3.1}, то сопоставьте их с { 0, 1, 2}, а также для y. тогда каждый прямоугольник может быть точно представлен этими упакованными целочисленными координатами.
Затем я бы выделил битвектор или что-то, что покрывает всю сетку, и растеризовал бы ваши прямоугольники в сетке. Ницца дело в том, что с сеткой действительно легко работать, и, ограничивая ее уникальными координатами x и y, она минимальна и точна.
Один из способов найти довольно быстрое решение - просто сбросить каждый "пиксель" вашей сетки.. прогоните их обратно через ваше отображение, и вы закончили. Если вы ищете более оптимальное количество прямоугольников, то у вас есть какая-то проблема с поиском.
Давайте посмотрим на 4 соседних пикселя, маленький квадрат 2x2. Когда я пишу алгоритмы, подобные этим, обычно я думаю в терминах вершин, ребер и граней. Итак, это лица вокруг Верта. Если 3 из них включены, а 1 выключен, то у вас есть вогнутый угол. Это единственный недопустимый случай. Например, если у меня нет вогнутых углов, я просто хватаю экстенты и сбрасываю все это как один прямоугольник. Для каждого вогнутого угла вам нужно решить, разделять ли его по горизонтали, вертикали или и то, и другое. Я думаю о расщеплении как о маркировке краев, которые нельзя пересекать при поиске экстентов. Вы также можете сделать это как раскрашивание в наборы, что для вас проще.Вогнутые углы и их расщепленные направления-это ваше пространство поиска.. вы можете использовать любой алгоритм оптимизации, который вам нравится. Ответвление / привязка может работать хорошо. Держу пари, что вы можете найти простую эвристику, которая хорошо работает (например, если есть еще один вогнутый угол прямо напротив того, который вы рассматриваете, всегда разделяйте в этом направлении. В противном случае разделите на более короткие направление). Ты можешь просто пожадничать. Или вы можете просто разделить каждый вогнутый Верт в обоих направлениях, что обычно даст вам меньше прямоугольников, чем вывод каждого "пикселя" в виде прямой линии, и будет довольно просто.
Перечитывая это, я понимаю, что могут быть неясные области. Дайте мне знать, если вы хотите, чтобы я что-нибудь прояснил.