Разделение KDTree

В настоящее время я пишу KDTree для физического движка (проект Хобби).

KDTree не содержит точек. Вместо этого он содержит ограничивающие рамки Axis Aligned, которые связывают разные объекты в среде.

Моя проблема заключается в том, как разбить узлы KDTree, когда они будут заполнены. Я пытаюсь использовать 2 метода:

Метод 1: Всегда разделяйте node ровно наполовину на самой большой оси.

  • Это имеет преимущество довольно равномерно распределенного дерева.
  • Большой недостаток: если объекты сконцентрированы в небольшой области node, будут созданы резервные подразделения. Это связано с тем, что все тома разделены ровно наполовину.

Метод2: найдите область node, которая содержит объекты. Разделите node на плоскости, которая разбивает эту область пополам на самой большой оси. Пример. Если все объекты сконцентрированы в нижней части node, тогда он разделяется по длине, тем самым разделяя дно на две части.

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

Итак, я ищу здесь лучший способ разбить KD-Tree node. Учитывая, что это будет физический движок, решение должно быть достаточно простым, чтобы его можно было сделать в режиме реального времени.

Ответы

Ответ 1

"Эвристика поверхности" (SAH) считается наилучшим методом расщепления для построения kd-деревьев, по крайней мере, в сообществе raytracing. Идея состоит в том, чтобы добавить плоскость так, чтобы поверхности двух дочерних пространств, взвешенных по количеству объектов в каждом ребенке, были равны.

Хорошая рекомендация по теме - тезис Инго Вальда, в частности глава 7.3 "Высококачественная конструкция BSP", которая объясняет SAH лучше чем я могу.

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

Все, что сказано, деревья ABB с размерами (BVH) a.k.a. AABB кажутся гораздо более популярными, чем kd-деревья в наши дни. Опять же, страница публикации Ingo Wald является хорошей отправной точкой, вероятно, с документом "Быстрое построение иерархии ограничений объема SAH", хотя это было в то время как я его читал.

форумы OMPF также являются хорошим местом для обсуждения подобных вещей.

Надеюсь, что это поможет. Удачи!

Ответ 2

Разумеется, для физического движка, где в помещении много движущейся геометрии, bvh, вероятно, лучший выбор, они не проходят так же быстро, но они намного быстрее собираются, и их намного легче переделать/реструктурировать кадр на каждый кадр и offen не нуждаются в полной перестройке, каждый кадр (что-то, что можно сделать параллельно по целому ряду кадров, в то время как переоборудованный bvh достаточно, опять же, ссылаться на wald).

Исключение из этого в физике может быть, когда вы имеете дело с сущностями, у которых нет тома, таких как частицы или фотоны, построение дерева kd упрощается из-за того, что вам не нужно разрешать границы индивидуальный примитив. Это действительно зависит от приложения. Хороший физический движок должен использовать сбалансированную комбинацию структур пространственного ускорения, обычно практикуется более широкое разделение фаз с использованием неглубокого окта, затем расширяют узлы листа другой схемой, которая лучше соответствует характеру того, что вы делаете, BSP идеально подходят для статической геометрии, особенно в 2d, и когда структура не меняется, лучше всего поэкспериментировать с множеством различных схем и структур и понять, как и когда они работают лучше всего.