Quadtree vs Red-Black tree для игры на C++?

Я давно искал в сети реализацию узла quadtree / quadtree. Есть кое-что базовое, но ничего, что я смог бы использовать в игре.

Моя цель - хранить объекты в игре для обработки таких вещей, как обнаружение столкновений. Я не на 100% уверен, что дерево квадрантов - лучшая структура данных для использования, но из того, что я прочитал, это так. Я уже написал красно-черное дерево, но я действительно не знаю, будет ли производительность достаточно хорошей для моей игры (которая будет приключенческой игрой от третьего лица, такой как Ankh).

Как мне написать базовый, но полный класс квадродерева (или октодерева) на C++? Как бы вы использовали дерево квадратов для столкновений?

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

unwind 16.12.2008 17:29
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
8
1
10 162
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Причина использования квадродерева заключается в том, что затем вы можете разделить по координатам x и y, октодерево по x, y и z, что делает обнаружение столкновений тривиальным.

Quadtree: если элемент не находится в верхнем левом углу, он не будет сталкиваться с элементом в верхнем правом, нижнем левом или нижнем правом.

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

Я бы не стал писать такой класс, просто позаимствовал бы его из проекта с подходящей лицензией.

точно. суть квадродерева не в быстром обходе дерева, а в том, чтобы в первую очередь избежать обхода.

Jimmy 16.12.2008 19:03

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

Ответ принят как подходящий

Quadtrees используются, когда вам нужно только хранить вещи, которые эффективно находятся в самолете. Как юниты в классической стратегии в реальном времени, где все они находятся на земле или чуть выше нее. По сути, каждый узел имеет связи с 4 дочерними узлами, которые делят пространство узла на равномерно распределенные четверти.

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

Если вы ищете двоичное дерево - например, красно-черное дерево - тогда вы хотите использовать структуру данных, называемую деревом разделения двоичного пространства (BSP-дерево), или ее версию, называемую KD Tree. Они разделяют пространство на половины с помощью плоскости, в дереве KD плоскости ортогональны (по осям XZ, XY, ZY), поэтому иногда это лучше работает в 3D-сцене. Деревья BSP разделяют сцену с помощью плоскостей в любой ориентации, но они могут быть весьма полезны, и они использовались еще в Doom.

Теперь, поскольку вы разделили игровое пространство, вам теперь не нужно тестировать каждую игровую сущность против каждой другой игровой сущности, чтобы увидеть, сталкиваются ли они, что в лучшем случае является алгоритмом O (n ^ 2). Вместо этого вы запрашиваете структуру данных, чтобы вернуть игровые объекты в подобласти игрового пространства, и выполняете обнаружение столкновений только для этих узлов друг с другом.

Это означает, что обнаружение столкновений для всех игровых сущностей должно быть nO (nlogn) операцией (в худшем случае).

Еще пара вещей, на которые следует обратить внимание:

  • Убедитесь, что вы тестируете игровые объекты из соседних узлов, а не только из текущего узла, поскольку они все еще могут столкнуться.
  • Перебалансируйте структуру данных после перемещения сущностей, поскольку теперь у вас могут быть пустые узлы в структуре данных или те, которые содержат слишком много сущностей для хорошей производительности (также вырожденный случай, когда все сущности находятся в одном узле).

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

Скорее всего, вы захотите отсортировать свои объекты на подвижные и статические и сравнить все, что перемещается в данном кадре, со статическими объектами.

Деревья BSP - это приемлемое решение для статической геометрии (граничные случаи обрабатываются путем разделения объекта на две части), для динамических попробуйте что-то вроде Sort and Sweep (также известных как Sweep и Prune).

Я настоятельно рекомендую вам использовать движок рендеринга, например Ogre3D. Насколько я знаю, он поддерживает Octrees для управления сценой. Но вы можете расширить класс на основе Octree по своему желанию. Раньше я сам кодировал то, что мне было нужно, но для сложных проектов это просто неправильно.

На данный момент STANN - лучшая реализация с открытым исходным кодом.

http://sites.google.com/a/compgeom.com/stann/

Другие вопросы по теме