如何计算包围其他边界球的最小边界球

问题描述 投票:0回答:3

我正在寻找一种有人可以访问的算法,该算法可以计算包围一组其他边界球的最小边界球。我对此已经思考了一段时间,并提出了一些初步的解决方案,但我不认为这些解决方案一定是最准确的或计算成本最低(最快)的。

第一个想法

我的第一个解决方案是最简单的天真的解决方案,即将球体中心平均以获得中心点,然后计算从计算的中心到每个球体中心的最大距离加上其半径,作为半径。所以伪代码如下:

function containing_sphere_1(spheres)
  center = sum(spheres.center) / count(spheres)
  radius = max(distance(center, spheres.center) + radius)
  return Sphere(center, radius)
end

但是我感觉它的计算量并不便宜,也不是很准确,因为生成的球体可能比需要的大很多。

第二个想法

我的第二个想法是使用迭代算法来计算最小边界球。它是通过连续测试另一个球体来计算的,如果测试的球体在边界内,则不执行任何操作,否则根据两个可用球体计算新的边界球体。如果新的边界球体延伸到球体表面,则新边界球体的中心位于两个中心之间的向量的一半,半径是该线长度的一半(从新中心到任一球体表面)。

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

最初我认为这将是要走的路,因为它是迭代的并且看起来逻辑上相当一致,但是在阅读了一些内容之后,最值得注意的是 Emo Welzl 的文章“最小的封闭圆盘(球和椭球体)”,我不是不太确定。

韦尔茨尔算法

据我了解,该算法的基础是 3 维中一组点的最小边界球体可以由最多 4 个点(位于封闭球体的表面上)确定。因此,该算法采用迭代方法,选择 4 个点,然后测试其他点以查看它们是否在内部,如果不是,则构建以新点为特征的新边界球。

现在该算法严格处理点,但我认为它可以应用于处理球体,主要的复杂性是在构造封闭球体时考虑半径。

回到问题

那么,为一组给定球体创建最小边界球体的“最佳”算法(计算成本最低)是什么?

我在这里描述的其中之一就是答案吗?一些伪代码或算法会很棒。

math collision-detection
3个回答
11
投票

从包围点到包围球的步骤并不简单,正如 K. Fischer 论文中的对 Welzl 算法(用于包围点)的讨论所解释的那样,“球中的最小包围球”。 参见第 2 节。 5.1.

第 4 章介绍“包围点”材料,然后第 5 章介绍“包围球体”。

Fisher 论文中描述的算法自 3.0 版本以来已在 CGAL 包中实现,如果您只是在寻找实现。


5
投票
https://en.wikipedia.org/wiki/Bounding_sphere

对于每个球体,找到其最小/最大 x/y/z 点。把这6点扔进一个桶里。当您完成所有 N 个球体后,您将获得一桶 6N 点。使用任何已知算法找到这些的边界球。

无论采用何种算法,您得到的边界球很可能会有点太小。然后,您可以执行 Ritter 方法的第二遍,但使用球体的背面作为测试点。 “背面”表示球体上距离当前 bnd 球体中心最远的点。如果球体的背面 pt 位于当前 bnd 球体之外,则增长 bnd 球体以将其包含在内。

除了 6 个极值点之外,您最初还可以包括内切立方体的 8 个角:

( [+/-]kR, [+/-]kR, [+/-]kR ),其中 k=sqrt(3)/3。这给出了 14 个点,这些点在测地线上分布得相当均匀。


0
投票

从第一种方法开始:找到点的平均值(可能按半径加权),并将其用作最小化算法(如

scipy.optimize.minimize

)的起点,最小化半径加距离的总和当前位置(边界球体的中心)和另一个球体之间。在Python中: import numpy as np from scipy.optimize import minimize # spheres given by centers = np.array([[x0,y0,z0],...]) # and radii = np.array([r0,...]) def dist(pos): return np.min(radii + np.linalg.norm(centers-pos[np.newaxis,:])) result = minimize(dist,x0=np.average(centers,axis=0,weights=radii)) bounding_center = result.x bounding_radius = result.fun

* 对于 N 个球体和最小化例程对函数的 F 次调用,时间复杂度为 O((1+F)*N)。

© www.soinside.com 2019 - 2024. All rights reserved.