Quadtree vs Red-Black tree для игры на C++?
Я искал реализацию узла quadtree/quadtree в сети в течение многих лет. Есть некоторые основные вещи, но ничего, что я мог бы действительно использовать его в игре.
моя цель-хранить объекты в игре для обработки таких вещей, как обнаружение столкновений. Я не на 100% уверен, что четырехугольник-лучшая структура данных для использования, но из того, что я прочитал. Я уже закодировал красно-черное дерево, но я действительно не знаю, будет ли производительность достаточно хорошей для моей игры (которая будет приключенческой игрой 3-го лица, такой как Ankh).
Как бы я написал базовый, но полный класс quadtree (или octree) на C++? Как бы вы использовали дерево quad для столкновений?
6 ответов
Quadtrees используются, когда вам нужно только хранить вещи, которые эффективно находятся на плоскости. Как единицы в классическом RTS, где они все на земле или просто немного выше. По существу, каждый узел имеет ссылки на 4 дочерних элемента, которые разделяют пространство узла на равномерно распределенные четверти.
Octrees делают то же самое, но во всех трех измерениях, а не только в двух, и, таким образом, они имеют 8 дочерних узлов и разделяют пространство на восьмерки. Они должны использоваться, когда игра сущности распределены более равномерно между всеми тремя измерениями.
Если вы ищете двоичное дерево-например, красно-черное дерево-тогда вы хотите использовать структуру данных, называемую деревом разделения двоичного пространства (BSP tree) или его версией, называемой деревом KD. Эти разделяют пространство на половины с помощью плоскости, в дереве KD плоскости ортогональны (на осях XZ, XY, ZY), поэтому иногда это работает лучше в 3D-сцене. Деревья BSP разделяют сцену, используя плоскости в любой ориентации, но они могут быть очень полезны, и они использовались еще в Doom.
теперь, поскольку вы разделили игровое пространство, вам теперь не нужно тестировать каждый игровой объект против каждого другого игрового объекта, чтобы увидеть, сталкиваются ли они, что является алгоритмом O(n^2) в лучшем случае. Вместо этого вы запрашиваете структуру данных, чтобы вернуть игровые объекты в пределах субрегиона игрового пространства и выполнять обнаружение столкновений только для этих узлов друг против друга.
Это означает, что обнаружение столкновений для всех игровых сущностей должна быть операция N O(nlogn) (в худшем случае).
пара дополнительных вещей, чтобы следить за:
- убедитесь, что вы тестируете игровые объекты из соседних узлов, а не только из текущего узла, поскольку они все еще могут сталкиваться.
- перебалансировка структуры данных после перемещения сущностей, так как теперь в структуре данных могут быть пустые узлы или те, которые содержат слишком много сущностей для хорошей производительности (также вырожденный случай всех лиц, находящихся в одном узле).
красно-черное дерево не является пространственным индексом; оно может сортировать только по одной порядковой клавише. Quadtree-это (для двух измерений) пространственный индекс, который позволяет быстро искать и удалять точки. В восьмеричного дерева набора делает то же самое для трех измерений.
причина использования quadtree заключается в том, что вы можете разделить на X - и y-координаты, octree на x, y и z, что делает обнаружение столкновений тривиальным.
Quadtree: если элемент не находится в topleft, он не столкнется с одним в topright, bottomleft или bottomright.
Это очень простой класс, поэтому я не понимаю, чего вам не хватает в реализации, которую вы нашли.
Я бы не стал писать такой класс, я бы просто взять его из проекта с подходящая лицензия.
Я настоятельно рекомендую вам использовать движок рендеринга, например Ogre3D. Насколько я знаю, он поддерживает Octrees для управления сценой. Но вы можете расширить класс на основе Octree, как вы хотите. Раньше я сам кодировал то, что мне нужно, но для сложных проектов это просто неправильный способ.
деревья вообще проблематичны для этого в том, что любой вставленный элемент может лежать на границе, и все методы борьбы с этой ситуацией довольно неудовлетворительны.
вы, скорее всего, захотите отсортировать свои объекты в подвижные и статические и проверить все, что двигалось на данном кадре, против статических объектов.
деревья BSP являются принятым решением для статической геометрии (граничные случаи обрабатываются путем разделения объекта на две части), для динамической попытки что-то вроде сортировки и подметания (также известное как подметание и чернослив).