【问题标题】:Find overlapping circles查找重叠的圆圈
【发布时间】:2016-07-23 22:19:34
【问题描述】:

我有一个矩形区域,其中有半径相等的圆。我想找出哪些圆圈与其他圆圈重叠(输出是重叠圆圈的 2 元素集列表)。

我知道如何检查两个圆是否重叠(它们的中心之间的距离小于直径)。我可以对每对圆执行此检查,但我想知道是否有更好的算法(比O(n^2) 更快)。

编辑

圆圈的数量通常在 100 左右,重叠不会经常发生。

这里有一些上下文: 矩形是游戏中的战场。单位的移动是小步完成的,我正在尝试检测单位之间的碰撞。

【问题讨论】:

  • 好问题。 :) 在我看来你可以做某种扫描线算法。
  • 嗯。 . .所有圆圈都可以与所有其他圆圈重叠。对我来说,这表明在最坏的情况下你不能比 O(n^2) 做得更好——尽管可能有启发式方法来优化它。
  • @GordonLinoff 我认为应该有一个输出敏感算法——一个运行时间与重叠数(和圈数)成正比的算法;这就是有点相关的段交叉问题的情况。
  • 你的问题不够精确。什么是预期的输出 ? n 圆圈可以形成一个链条,其中任何一个都与另外两个完全重叠。这种情况下的输出是什么?
  • n 有多大?

标签: algorithm data-structures computational-geometry


【解决方案1】:

鉴于问题陈述的新解释,我会推荐一种不同的方法。

在战场上覆盖一个方形网格,网格步长等于一个圆的直径。每个圆圈最多可以重叠四个单元格。在每个单元格中,保留重叠圆圈的列表(并在每次移动时更新它)。

检测潜在的碰撞现在每个圆圈需要大约四次细胞/圆圈测试,即接近线性时间。

【讨论】:

    【解决方案2】:

    对于一个简单的解决方案,将中心插入二维树中,并围绕每个中心执行圆形范围查询,查询半径为 2R。在良好的条件下,这可以是 O(N Log(N))。


    或者,只需对 X 上的中心进行排序,然后依次尝试所有圆:通过二分搜索,定位横坐标 Xc 并扫描到 Xc-2R 和 Xc+2R,然后检查 2D 距离。

    二分搜索的成本将是 O(N Log(N))。如果圆圈均匀分布在 S 边的正方形中,则宽度为 4R 的条带包含 4RN/S 个圆圈,因此总比较成本为 4RN²/S。如果 S 很大,这是一个很好的性能(认为对于正方形中的 N 个紧密排列的圆,S~2R√N,因此有 2N√N 个比较)。

    【讨论】:

    • 鉴于 N 的值较低,不确定这是否能击败穷举搜索:(
    【解决方案3】:

    直接答案:一般情况下,你不可能比 O(n^2) 更好,因为圆圈可能全部重叠,所以你必须生成 n^2 个答案。

    如果你得到更具体的答案,你可能会得到更好的答案。例如,如果您真正想做的是在 2D 模拟中找到边界球体,您可以从实体仅在帧之间移动这么远的事实中受益,如果圆圈稀疏,则与紧密排列时不同,等等. 所以让我们更多地了解它的全部内容。

    编辑:您编辑了您的问题 - 您确实正在寻找 2D 模拟中的碰撞检测。如果您查看 https://en.wikipedia.org/wiki/Collision_detection ,他们会针对您的情况指出几种算法。

    我喜欢该页面上的一个详细权利,您可以在其中保留每个轴的一个边界间隔列表(“2D”中的 2 个),并且只需要在这些边界间隔(根据定义本身是一维的)时“努力工作” ) 变化(即出现“重叠状态”)。对于行为良好的情况,这将删除 O(n²)。他们没有给出其复杂性的估计,但由于它基本上归结为排序,在我看来或多或少O(n logn),而当帧之间只有很小的变化时则更少。

    【讨论】:

    • O(N²),在最坏的情况下确实不可避免,很可能是悲观的。
    • 是的,指出这是我的意图——如果 OP 给我们提供更具体的信息,我们可以考虑其他解决方案。所以他做到了,事实上,我会编辑答案。 :)
    猜你喜欢
    • 2021-03-21
    • 1970-01-01
    • 1970-01-01
    • 2016-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    相关资源
    最近更新 更多