【问题标题】:Optimization in collision detection碰撞检测优化
【发布时间】:2012-01-25 08:51:58
【问题描述】:

我正在搜索有关优化碰撞检测的信息。

有一个物体(圆)从点a移动到点b。这个物体的半径为r,而且场内也有很多障碍物(圆)。

我有一个算法(函数)来检查圆和胶囊之间的碰撞,我目前为每个障碍物调用这个函数:

for-each (o : obstacles)
  if collide(o, Capsule(a,b,r))
    return true;

return false;

许多障碍物距离运动物体很远,可以通过碰撞检测功能忽略它们。

我的问题是:

是否有解决方案可以忽略使用碰撞检测功能检查所有障碍物? 最近邻搜索KD树之类的?


编辑:所有障碍物的半径相同。

【问题讨论】:

  • 你有多少障碍?它们的密度是多少?碰撞是经常发生还是很少发生?
  • 想想 100 个障碍物,它们是稀疏分布的。算法每 10 毫秒调用一次。
  • 我认为我的程序的关键是这个问题。
  • 您应该尝试分析您的程序以确保您找到了瓶颈。另外,kd-tree 似乎适合您的问题,如果有帮助,您尝试过吗?
  • 我之前使用 kd-tree 来查找离给定点最近的点。但是这种情况下不知道怎么用kd-tree!

标签: algorithm optimization collision-detection


【解决方案1】:

作为第一步,您可以忽略不在某个框架/框内的所有障碍物。

例如所有 y - 坐标(障碍物形状的 y - 最低点)大于 a 和 b 的最大 y 坐标 + 移动物体半径的相同距离的所有障碍物都可以忽略。下 y 边界和 x 边界类似。 您可以将类似的东西进一步分支成两个(或更多)盒子,而不是一个盒子。例如购买将 a-b 的距离分成两个距离,并对 (a, (b-a)/2), /(b-a)/2, b) 中的每一个执行上述过程。

但这一切都取决于您将这些值与您的碰撞过程进行比较的效率。

【讨论】:

    【解决方案2】:

    您可以简单地使用网格,其中每个单元格包含所有与该单元格接触的障碍物。现在只检查你的胶囊接触的细胞。 您也可以使用四叉树,但根据我的经验,网格通常就足够了,并且还具有在障碍物移动时可以轻松快速地更新的优点。

    【讨论】:

      【解决方案3】:

      对马丁回答的评论:

      我做了一个像Box(a.x-R, a.y-R, b.x+R, b.y+R) 这样的盒子,其中RObjectRadius + ObstacleRadius,然后放下所有不在盒子里的障碍物。图中只检查带黄点的障碍物:

      【讨论】:

      • 这看起来很不错。尽管您可能需要稍微扩展该框,以使所有粉红色路径(+ security R)都包含在其中(上面我假设a和b通过一条线连接)。较小的黑线表示什么?
      • 是没有R保护的盒子。它工作正常,我不得不在几个地方编辑我的代码。
      【解决方案4】:

      我可以推荐一条怪物曲线,例如希尔伯特曲线。它是一个四叉树或 kd 树之类的数据结构,它将 2d 复杂性降低为 1d 问题。在每一帧,您都可以从头开始构建怪物曲线,这样就可以避免在四叉树或 kd 树中删除或插入。它还具有一些更好的 2d 平铺属性,但在您的情况下可能不需要。

      【讨论】:

        【解决方案5】:
        1. 将障碍物中心放入 KD-tree。
        2. 找到最近的中心。
        3. 检查它是否比 ObstacleRadius 更近。

        【讨论】:

          【解决方案6】:

          您可以尝试在代码中实现空间分区。通过将每个对象/障碍物划分为覆盖整个空间或地图的每个框。通过这样做,您可以将障碍分成多个部分。因此,您可以通过仅检查一小部分内的碰撞来大量减少碰撞检查。如果您的障碍物没有移动,您只需为每个障碍物执行一次此分区。如果它们在移动,您必须每次更新每个障碍物的分区 [Regrouping]。

          空间分区技术已经存在了很长一段时间,这里有一个链接可以帮助您进行实施。

          http://gameprogrammingpatterns.com/spatial-partition.html

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2023-04-04
            • 1970-01-01
            • 2013-05-30
            • 1970-01-01
            • 2011-09-05
            • 2019-04-30
            • 1970-01-01
            相关资源
            最近更新 更多