Найти прямоугольники, содержащие точку - эффективный алгоритм
Добрый день.
Моя ситуация:
- В двухмерном пространстве.
- Ввод: набор прямоугольников (тоже перекрывающиеся прямоугольники).
- Координаты прямоугольников имеют целочисленный тип.
- Нет никаких ограничений на размер прямоугольника и местоположение прямоугольника (только экстент целого числа).
- Ни один прямоугольник не имеет ширину = 0 или высоту = 0.
- Мне нужно найти: все прямоугольники, которые содержат введенную точку (с целочисленными координатами).
![Find rectangles that contain entered point.]()
Вопросы:
- Какова эффективная структура для хранения прямоугольников?
- Какой алгоритм эффективен в этом случае?
- И какой алгоритм эффективен только для добавления прямоугольников без удаления?
Спасибо :-).
Ответы
Ответ 1
R-Tree - лучшая структура данных, подходящая для этого варианта использования. R-деревья - это древовидные структуры данных, используемые для методов пространственного доступа, то есть для индексирования многомерной информации, такой как географические координаты, прямоугольники или многоугольники. Информация о всех прямоугольниках может храниться в виде дерева, поэтому поиск будет легким.
Wikipedia, short ppt и исследовательская статья поможет вам понять концепцию.
![enter image description here]()
Ответ 2
В java вы можете использовать shape.contains
Но в целом, если предположить, что прямоугольник определяется (x, y, width, height), вы делаете
if (pt.x >= x && pt.x <= x + width & pt.y >= y & pt.y <= y + height)...
Если у вас есть все ваши прямоугольники в коллекции, вы можете перебирать коллекцию и находить те, которые содержат точку
Ответ 3
Прямоугольник (left, top, right, bottom)
содержит точку (x, y)
, если left < x < right
и top < y < bottom
(при условии, что координаты увеличиваются вниз, что имеет место с большинством аппаратных средств, которые я видел; если ваши координаты увеличиваются вверх, тем больше традиционно математический случай, swap top
и bottom
). Вы не будете намного эффективнее, чем тест.
Если вы рассматриваете прямоугольник как "содержащий" точку, если она также находится на границе, замените все <
на <=
.
Что касается того, что делать с коллекцией прямоугольников... я не знаю. Я бы подумал, что список, отсортированный по координатам углов, сделает что-то, но я не вижу в этом большой пользы... в лучшем случае вы бы сократили свой список вещей, чтобы проверить половину, в среднем (в худшем случае все еще требуется проверить все). Половина целой чертовой партии все еще может быть много.:)
Ответ 4
Кажется, что ваш набор прямоугольников может быть динамическим ( "... для добавления прямоугольников..." ). В этом случае - 2D Дерево интервала может быть решением.
Ответ 5
Вот простое решение.
- Определите сетку на плоскости.
- Каждая ячейка поддерживает два списка: прямоугольники, которые полностью покрывают эту ячейку, и прямоугольники, которые частично покрывают эту ячейку.
- В каждой вставке поместите идентификатор целевого прямоугольника во все задействованные списки ячеек.
- В каждом запросе найдите ячейку, содержащую целевую точку, выведите полный список обложек и выполните проверку в частичном списке обложек.