我正在寻找一个有人可以访问的算法,它将计算包含一组其他边界球体的最小边界球体。我已经考虑了一段时间并提出了一些初步的解决方案,但我不相信这些解决方案必须是最准确或最不昂贵的(最快的)。
我的第一个解决方案是最简单的天真解决方案,即平均球形中心以获得中心点,然后计算从计算中心到每个球体中心的最大距离加上其半径,作为半径。所以伪代码就像:
function containing_sphere_1(spheres)
center = sum(spheres.center) / count(spheres)
radius = max(distance(center, spheres.center) + radius)
return Sphere(center, radius)
end
然而,我感觉它不是那么便宜,也不是很准确,因为得到的球体可能比它需要的大得多。
我的第二个想法是使用迭代算法来计算最小边界球。它是通过连续测试另一个球体来计算的,如果测试的球体在边界内,则不做任何事情,否则从可用的两个球体计算新的边界球体。新的边界球体的中心位于两个中心之间的矢量之间,如果它延伸到球体表面,半径是该线条长度的一半(从新中心到球体表面)。 / p>
function containing_sphere_2(spheres)
bounds = first(spheres)
for each sphere in spheres
if bounds does not contain sphere
line = vector(bounds.center, sphere.center)
extend(line, bounds.radius)
extend(line, sphere.radius)
center = midpoint(line)
radius = length(line) / 2
bounds = Sphere(center, radius)
end
end
return bounds
end
起初我以为这将是要走的路,因为它是迭代的,似乎相当逻辑上一致,但是通过莫·韦尔泽我做一些阅读,最引人注目的文章“最小包围盘(球和椭球)”后”我不太确定。
据我所知,该算法的基础是3维中一组点上的最小边界球可以由最多4个点(在封闭球体的表面上)确定。因此,该算法通过选择4个点进行迭代,然后测试其他点以查看它们是否在内部,如果它们不是新的边界球,则构造特征为新点。
现在算法严格处理点,但我认为它可以应用于处理球体,主要复杂因素在构造封闭球体时会对半径产生影响。
那么什么是'最佳',至少是计算成本最高的算法,为一组给定的球体创建一个最小的边界球?
我在这里描述了其中一个答案吗?一些伪代码或算法会很棒。
答案 0 :(得分:10)
从封闭点到封闭球体的步骤非常重要,正如K. Fischer的论文中的discussion of Welzl's algorithm (which works to enclose points)所解释的那样,“最小的球包围”。见第二节。 5.1。
第4章介绍了“封闭点”材料,然后第5章介绍了“封闭球体”。
如果你只是在寻找一个实现,那么自从3.0版以来,Fisher论文中描述的算法就已经实现了in the CGAL package。
答案 1 :(得分:0)
这是一种基于Ritter算法的快速近似最优方法 https://en.wikipedia.org/wiki/Bounding_sphere:
对于每个球体,找到其最小/最大x / y / z点。将这6个点扔进水桶。当你完成所有N个球体时,你将拥有6N点的一桶。使用任何已知算法为这些找到边界球。
无论算法如何,你获得的边界球很可能会有点太小。然后你可以进行Ritter方法的第二次传递,但是使用球体的背面作为要测试的点。 '背面'意味着球体离目前的球体中心最远的球体。如果球体的背面pt在当前的bnd球体之外,则生长bnd球体以包含它。
除了6个极值之外,您最初可以包含刻录立方体的8个角:
([+/-] kR,[+/-] kR,[+/-] kR),其中k = sqrt(3)/ 3。这给出了14个分布相当均匀的地理位置。