一尘不染

KDTree拆分

algorithm

我目前正在为物理引擎(Hobby项目)编写KDTree。

KDTree不包含点。取而代之的是,它包含“轴对齐”边界框,该边界框对环境中的不同对象进行边界。

我的问题是决定如何在KDTree节点已满时拆分它们。我正在尝试2种方法:

方法1:始终将节点在最大轴上精确地一分为二。

  • 这样的好处是树的间距相当均匀。
  • 很大的缺点:如果对象集中在节点的较小区域中,则会创建多余的细分。这是因为所有卷都被精确地分成两半。

方法2:查找包含对象的节点的区域。在平面上拆分节点,该节点在最大轴上将该区域拆分为一半。示例-
如果所有对象都集中在节点的底部,则它将沿长度方向拆分,从而将底部一分为二。

  • 这解决了以上方法的问题
  • 当索引同一平面上存在的某物(例如地形)时,它将创建长而窄的节点。如果以后要添加其他不在同一平面上的其他对象,则这些拉长的节点将提供非常差的索引。

因此,我在这里寻找的是拆分KD-Tree节点的更好方法。考虑到这将成为物理引擎,因此决策必须足够简单以实时进行。


阅读 287

收藏
2020-07-28

共1个答案

一尘不染

至少在光线跟踪社区中,“表面积启发式”(SAH)被认为是构建kd树的最佳拆分方法。想法是添加平面,以使两个子空间的表面积(由每个子对象中objexts的数量加权)相等。

关于此主题的一个很好的参考是Ingo
Wald的论文
,尤其是第7.3章“高质量的BSP构建”,它比我能更好地解释SAH。

目前,我找不到很好的链接,但是您应该四处寻找有关“装箱” SAH的论文,它是真实SAH的近似值,但速度更快。

话虽这么说,包围体积层次(BVH)又称AABB树,如今似乎比kd树更受欢迎。同样,Ingo
Wald的出版物页面
是一个不错的起点,可能是“基于SAH的边界体积层次结构的快速构建”一文,尽管自阅读以来已有一段时间。

OMPF论坛也是一个不错的地方来讨论这些事情。

希望有帮助。祝好运!

2020-07-28