快速球 - 网格交叉

时间:2010-02-22 08:01:48

标签: algorithm grid geometry intersection

给定一个3D网格,一个3d点作为球体中心和一个半径,我想快速计算球体所包含或相交的所有细胞。

目前我采用球体的(网格对齐的)边界框并计算此边界框的最小焦点最大点的两个单元格。然后,对于这两个单元格之间的每个单元格,我进行箱形球面相交测试。

如果有更高效的话,

会很棒

谢谢!

2 个答案:

答案 0 :(得分:2)

有一个用于绘制圆圈的Bresenham算法版本。考虑z = 0处的二维位置(假设球体现在处于0,0,0),并且仅查看网格点的x-y平面。从x = R,y = 0开始,遵循Bresenham算法直到y = y_R,x = 0,除了绘图之外,您只需使用结果就知道具有较低x坐标的所有网格点都在圆内,向下到x = x_center。将它们放在列表中,计算它们或以其他方式记录。当完成二维问题时,用变化的z重复并使用减小的半径R(z)= sqrt(R ^ 2-z ^ 2)代替R,直到z = R.

如果球体中心确实位于网格点上,您知道球体右半部分内部或外部的每个网格点在左侧都有一个镜像伙伴,同样在顶部/底部,所以你可以做到一半每个维度的计数/列表。您还可以节省将Bresenham运行到45度线的时间,因为相对于中心的任何x,y点都有一个伙伴y,x。如果球体可以在任何地方,则必须计算每个八分圆的结果。

答案 1 :(得分:1)

无论您如何有效地计算球体内部或外部的单个细胞,您的算法将始终为O(半径^ 3),因为您必须标记那么多细胞。 DarenW对中点(又名Bresenham)圆算法的建议可以给出一个恒定的因子加速,因为可以简单地使用平方半径测试交集以避免sqrt()调用。

如果你想要比O(r ^ 3)更好的性能,那么你可以使用octree而不是平面网格。树的每个节点可以被标记为完全在内部,完全在外部或部分在球体内部。对于部分内部节点,您可以向下递归树,直到获得最细粒度的单元格。这仍然需要标记O(r ^ 2 log r)节点[O(r ^ 2)节点在边界上,O(log r)逐步穿过树来到达每个节点],所以它可能不值得在您的申请中遇到麻烦。