【问题标题】:Distance between two polylines两条折线之间的距离
【发布时间】:2017-08-24 12:19:33
【问题描述】:

我要计算两条折线之间的距离d

显然我可以检查所有线段对的距离并选择最小的距离,但是这样算法的运行时间将是 O(n2)。有没有更好的办法?

【问题讨论】:

  • 这看起来像是 quadtrees 可能有用的东西 - 但在我看来,没有什么比这更有用了。
  • 不知道答案,但我猜一些基于四叉树的算法一定是可能的,你只计算附近元素之间的点线距离。
  • 基于边界框的方法可能会有所帮助。计算部分折线的边界框(例如,A 中的点 1...4、4...7 和 B 中的 8...10、10...12)。对于每对框,您可以计算最小和最大距离并丢弃无法与最佳对竞争的对,递归地细化框,直到它们都是 2 点(1 线)框,您可以在其中精确计算。似乎是 O(N logN)。
  • 在您的示例中,最近的点位于折线的顶点,这只是一种特殊情况 - 如果 2 条线段相交但该交点处没有顶点,则距离是否为零?
  • 是——如果两个线段相交,它们的距离为零。

标签: algorithm performance computational-geometry


【解决方案1】:

分而治之:

  • 定义一个数据结构,表示一对折线和它们之间的最小距离axis-aligned minimum bounding boxes (AAMBB):pair = (poly_a, poly_b, d_ab))

  • pair数据结构创建一个空队列,使用距离d_ab作为键。

  • 使用初始折线创建pair 数据结构并将其推入队列。

  • 我们将保留一个变量,其中包含到目前为止找到的多段线之间的最小距离 (min_d)。将其设置为无限。

  • 重复:

    • 从队列中弹出距离最小的元素d_ab

    • 如果d_ab 大于min_d,我们就完成了。

    • 如果任何折线poly_apoly_b 包含唯一线段:

      • 使用蛮力找出两者之间的最小距离并相应地更新min_d
    • 否则:

      • 将两条折线poly_apoly_b 分成两半,例如:

        (1-7) --> { (1-4), (4-7) }

        (8-12) --> { (8-10), (10-12) }

      • 做两个集合的叉积,创建4个新的pair数据结构,然后推入队列Q。

平均情况下,复杂度为 O(N * log N),最坏情况可能为 O(N²)。

更新algorithm 在 Perl 中实现。

【讨论】:

    【解决方案2】:

    此类问题的“标准”方法是构建几何实体的 Voronoi 图。这可以在 O(N Log N) 时间内完成。

    但是为线段构建此类图表很困难,您应该求助于现成的解决方案,例如 CGAL。

    【讨论】:

    • 一个 voronoi gram 可用作查找表,用于从任何地方查找最近的点,如果这些点不会改变并且您必须从许多其他点查找最近的点,那么它可能是值得的它生成 voronoi 以加快查找速度。但我看不到它如何帮助计算两条折线之间的距离?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-26
    • 2018-07-14
    • 2011-02-18
    • 2021-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多