【发布时间】:2016-12-13 19:54:46
【问题描述】:
Kd 算法从创建 BSP 根节点开始,通过划分基元数组(三角形、球体等)来创建两个新数组(左右基元),用于创建其两个子树。
通过将给定的基元数组划分为两个数组来计算左右基元。通过取每个三角形的区间(投影到给定轴(x,y或z)上)的中点的中值来计算分割平面位置。
例如,具有 x 坐标的三角形:1、2、3 的中点为 1=(3-1)/2(沿 x 轴) 具有 x 坐标的三角形:2、3、8 的中点为 3=(8-2)/2(沿 x 轴) 具有 x 坐标的三角形:4、3、8 的中点为 2.5=(8-3)/2(沿 x 轴) 包含这三个三角形的原始数组由一个平面划分,通过 x=2.5(中值)平行于 yz 平面。生成的左图元数组包含三个三角形,生成的右图元数组包含三个三角形。
得到的两个带有左右基元的数组用于构造 Kd 节点的左右子树(基元只存储在叶节点处)。
对于左子树:
If (the left primitives are empty) then the left subtree points to NULL
else if (the number of left primitives is smaller than the minimal number || the depth == 1) then the left subtree is a leaf node
else the left subtree is another tree.
create the left subtree with the left primitives along the axis (++axis % 3) with --depth as depth and the same minimal number.
右子树类似。
实现的算法有效,但速度很慢,因为树的分区不是很好。对 5500 个三角形的兔子进行光线追踪时,1 个三角形的叶节点很多,而最后一个叶节点仍然包含 762 个三角形。
是否有更好的分区算法(因为我的只是一个 Kd 树的实现,用于将单点转换为表面),可以平衡树?
更新:我搜索了一种算法或启发式算法,可以根据切割点将区间数组 [t0,t1] 划分为两个区间数组。左侧数组包含切割点左侧的间隔和包含切割点的间隔。类似于正确的阵列。两个数组必须具有大致相同的间隔数,并且重复间隔的数量必须尽可能少。这个算法的复杂度可能不是 O(n^2)。
【问题讨论】:
-
我对您问题中三角形的中点感到困惑。对于 x 坐标为 2,3,8 的三角形,为什么中点不是 2 + (8-2)/2 = 5? x 坐标为 1,2,3 的三角形应该有中点 1 + (3-1)/2 = 2 不是吗?这可能是具有 1 个三角形或 > 700 个三角形的非常不平衡的叶子的问题吗?
-
@PeteUK:你说得对:我没有在问题和代码中都包含偏移量。所以这可能是问题所在(完整的兔子模型以原点为中心,因此如果翻译它可能会更糟)。为了确定(但我们可以肯定),我将不再对此进行测试,因为它已经可以追溯到 2013 年(并且上述任何内容都没有出现在也可以追溯到 2013 年的最新版本中)。你终于可以回答这个问题了:)。
标签: raytracing bsp