【问题标题】:How to compute the smallest bounding sphere enclosing other bounding spheres如何计算包围其他边界球的最小边界球
【发布时间】:2012-02-22 05:20:18
【问题描述】:

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

最初的想法

我的第一个解决方案是最简单朴素的一个,就是将球心平均得到中心点,然后计算计算出的中心到每个球心的最大距离加上它的半径,作为半径。所以伪代码如下:

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 的文章“Smallest enclosure disks (balls and ellipsoids)”我不太确定。

Welzl 算法

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

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

回到问题

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

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

【问题讨论】:

  • 如果您使用加权质心(按半径)而不是纯质心,似乎可以使您的幼稚方法起作用。也就是说,边界球的中心应该比小球的中心更靠近大球的中心。
  • 不幸的是,我认为这种天真的方法行不通,hacksoflife.blogspot.com/2009/01/… 似乎表明有很多反例它会崩溃。它将创建一个封闭的球体,但不一定是最小的。
  • This 2008 paper by Thomas Larsson 有一个有用的边界球算法参考书目(用于点的集合,而不是球的集合)。
  • 我不是数学家(可能应该感兴趣地关注这个),但是......是否值得在球体周围画一个边界 box 然后画一个边界围绕那个?我想它仍然需要大量计算来确定盒子的大小,但它不会简化计算每次迭代的原点移动吗?此外,它仍然不一定是最小的,但会比具有固定来源的选项 1 更小。只是一个想法......
  • 事实证明 Welzl 的算法不适用于球体,请参阅我在 inf.ethz.ch/personal/emo/DoctThesisFiles/fischer05.pdf 的论文,p。 93 为反例。但是,正如@hardmath 的回答中所述,CGAL 中提供了一个非常快速的 C++ 实现。

标签: math collision-detection


【解决方案1】:

正如 K. Fischer 的论文中的 discussion of Welzl's algorithm (which works to enclose points) 所解释的那样,从封闭点到封闭球体的步骤非常重要,“最小的封闭球”。见秒。 5.1.

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

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

【讨论】:

  • 非常感谢您提供这篇文章的链接,这篇文章读起来很精彩,看起来很全面。
  • 只是为了补充您非常准确的答案:CGAL 实现为 minsphere of spheres 的情况提供了浮点和精确算术实现。您不必使用所有 CGAL,只需提取所需的标头即可。 – 对于 minsphere of points 的情况,github.com/hbf/miniball 上提供了一个 C++ 库。
【解决方案2】:

这是一种基于 Ritter 算法的快速、接近最优的方法 https://en.wikipedia.org/wiki/Bounding_sphere

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

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

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

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

【讨论】:

    猜你喜欢
    • 2023-03-23
    • 1970-01-01
    • 2011-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-10
    • 2013-11-23
    • 1970-01-01
    相关资源
    最近更新 更多