Разделение 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, и когда структура не меняется, лучше всего поэкспериментировать с множеством различных схем и структур и понять, как и когда они работают лучше всего.