【问题标题】:Fastest way to find sphere a point is inside and closest to找到一个点在内部并且最接近的球体的最快方法
【发布时间】:2018-06-13 18:54:28
【问题描述】:

在 3D 系统中,我有一堆不同半径的球体散布在各处。

确定一个点在哪个球体内的最快方法是什么,以及它是否在多个球体内 - 也是基于球体中心的最近球体。

bruteforce 方法是简单地遍历所有球体,计算到该点的距离,检查该距离是否小于球体的半径,然后找到距离最短的球体。

但是,我有几百万个点要检查(大约有 10 万个球体),所以这会非常慢。

我的另一个想法是构建某种 BVH Acceleration 结构,并为每个单元保存最接近的球体。但是,也存在一个单元格可能被两个或多个球体重叠的情况等。因此需要考虑很多边缘情况。

毕竟,BVH 树的计算不应该比蛮力慢。

有什么想法吗?

【问题讨论】:

  • 检查距离平方是否小于半径平方。不需要所有那些缓慢的平方根。
  • 对空间进行分区。
  • 查找“八叉树”以了解空间分区的常用方法。

标签: algorithm performance 3d octree


【解决方案1】:

我最终通过 OpenCL 在 GPU 上使用蛮力方法完成了它 - 超级快 :)

【讨论】:

    【解决方案2】:

    也许 清扫和修剪¹ 式的方法可以在这里工作?

    Handwavy 算法(2D 案例):

    1. 创建两个数组AxAy
    2. n 个圆中选择一个圆并投影到 x 轴上,即将圆心的 x 分量加上减去半径存储在 Ax 中。将圆也投影到 y 轴上。
    3. 对所有剩余的圆圈重复第 2 步。
    4. 将每个点的分量也存储在 AxAy 中。
    5. 排序AxAy

    从这里开始,一个点 P 只能在一个球体 S 内,前提是它包含在 S 的所有三个区间内。

    现在,可以确定每个点是否包含在球体中:迭代 Ax 并在每次“输入”间隔时递增计数器 k并在您“退出”一个间隔时减少 k。如果当您扫入一个点时计数器为 k,则该点包含在 k 个间隔的集合 I 中。检查该点是否包含在 Ay² 中任何对应的 I 区间内。

    同样,AxAy 的排序应该有助于找到最接近某个点的球体。

    我相信这种方法可以(大大)改进,并且在实践中并行化的蛮力可能会更快。

    Handwavy 算法(3D 案例):类似于 2D 案例。

    ¹。 http://www.cs.jhu.edu/~cohen/Publications/icollide.pdf

    ²。我显然省略了很多 d̶e̶t̶a̶i̶l̶s̶̶I̶̶h̶a̶v̶e̶̶y̶e̶t̶̶t̶o̶̶f̶i̶g̶u̶r̶e̶̶o̶u̶t 无聊的簿记细节。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-28
      • 2011-05-20
      • 1970-01-01
      • 1970-01-01
      • 2019-12-07
      • 2013-12-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多