Попытка использовать quadtrees для обнаружения столкновений в игре

В настоящее время я реализую систему обнаружения столкновений с использованием quadtrees. Я смог реализовать дерево квадрантов, но у меня возник вопрос относительно конкретной ситуации. Допустим, мое исходное дерево квадрантов имеет границу 200x200. Таким образом, мой 1-й уровень поддеревьев будет иметь границу:

NW: (0, 0) ~ (100,100)

SW: (0, 100) ~ (100, 200)

NE: (100, 0) ~ (200, 100)

SE: (100, 100) ~ (200, 200)

Допустим, есть квадратный объект в (98, 98), а его ширина и высота равны 5. Я беру центральное положение при вставке их в поддеревья, поэтому этот объект будет помещен в дерево квадрантов СЗ. Однако, поскольку его ширина и высота равны 5, технически они есть и на всех остальных трех деревьях квадрантов. Должен ли я проверять, простирается ли граница объекта на другую сторону дерева квадрантов, и если да, то добавлять несколько экземпляров в дерево квадрантов?


person dwnenr    schedule 22.11.2015    source источник
comment
Если вы создаете обнаружение 2D-столкновений, рассмотрите возможность использования фиксированной сетки. Это почти наверняка быстрее (особенно если размер ячейки выбран тщательно), потому что это будет операция O (1), чтобы узнать, какие ячейки охватывает объект.   -  person juzzlin    schedule 24.11.2015


Ответы (1)


Да - либо так, либо при вставке разделите свой квадрат на 4 отдельных в этом случае. Проще просто разрешить хранение дубликатов на листьях и сделать это дешевым (например, указатель/индекс на квадрат)

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

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

Я бы посоветовал начать с дубликатов. Другие методы могут быть настоящими хлопотами, и не нужно заморачиваться с такими хлопотами (пока вы не измерите потребность в этом).

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

Кроме того, для 2D-случаев иногда можно обойтись фиксированной сеткой. На самом деле иногда может работать лучше просто иметь сетку NxM, чем квадродерево, поскольку его очень просто построить (что упрощает быстрое обновление для очень динамичного контента, когда у вас есть, скажем, спрайты, перемещающиеся по экрану каждый кадр) , и не имеет сложных сценариев наихудшего случая, поскольку в нем нет понятия «глубина», а только ячейки, содержащие элементы.

person Community    schedule 22.11.2015