【问题标题】:Algorithm for the decomposition of polygons多边形分解算法
【发布时间】:2014-03-14 23:20:11
【问题描述】:

有没有人知道一种相对快速的算法,可以将一组多边形分解为它们不同的重叠和非重叠区域,即给定一组 n 个多边形,找到它们之间的所有不同区域?

例如,输入将是代表圆形的 4 个多边形,如下所示

输出将是所有多边形,代表以不同颜色显示的不同区域。

我可以使用多边形操作编写自己的实现,但该算法可能会很慢而且很耗时。我想知道是否有针对此类问题的优化算法。

【问题讨论】:

  • 您可能会想要某种扫描线算法,但它是非标准的,并且可能非常不容易高效地实现(多对数线性)
  • 每个算法都“相对较快”——除了可能是最慢的算法,但无论如何这都包含一个无限循环。说真的:稳健地计算多边形的交点已经够难了(理论上,这很容易,但考虑到浮点运算的精度有限,以及点/线的“边界情况地狱”(几乎)重合,我会警惕自己实施这个)。我假设当您要求“相对快速”的算法时,您想排除对所有多边形及其交点进行成对测试的明显算法?你有多少个多边形?
  • @Marco13 我正在开发一个接受 2-8 个多边形的程序,但是是的,如果可能的话,我宁愿不测试所有可能的组合。
  • 对于这么少的多边形,任何编写“非暴力”算法的尝试都是不值得的。但是如果你想这样做:在最坏的情况下,每个多边形与每个其他多边形(以及其他多边形对的每个相交)无论如何(就像在你的例子中一样! )。我目前能想到的唯一可能的优化是某种en.wikipedia.org/wiki/Bounding_volume_hierarchy,以快速排除肯定相交的多边形。对于您的应用案例,这可能是一种可行的方法吗?
  • 感谢您提出我已经得到答案的问题 :-) +1。

标签: algorithm polygon intersection polygons convex-polygon


【解决方案1】:

我认为这并不难。 我已经在友好网站上回答了类似的问题,并由一个较小的社区进行了检查: https://cs.stackexchange.com/questions/20039/detect-closed-shapes-formed-by-points/20247#20247

  • 让我们寻找一个更常见的问题 - 让我们使用曲线而不是多边形。让我们允许它们超出图片边界,但我们只计算完全属于图片的简单多边形。
  • 通过检查属于不同曲线的所有线段对来查找所有交点。当然,在真正检查相交之前过滤它们。
  • 为所有曲线编号 1..n。在其中设置一些段的顺序。
  • 为每个点创建一个交点序列 SOI,因此:如果它从边界端开始,SOI[1] 为空。如果不是,SOI[1]=(与它相交的第一条曲线的编号,相交曲线上向左移动的符号)。继续,在 SOI 中记录每个交叉点 - 如果有曲线,则为曲线数,如果是与边界的交叉点,则为 0。
  • 显然,您只寻找简单的边界区域,内部没有曲线。
  • 两个相邻的非空交点之间的曲线段,我们将其称为段。
  • 为每条曲线设置 SOI:
    • 对于曲线 1 的线段,从线段的第一个点开始,进行 2 次尝试绘制线段的多边形。它是 2,因为您可以沿着第一条相交曲线前往 2 条边。
    • 尝试右转时,只做左转,尝试左转,只做右转。
    • 如果您到达的点没有正确方向的路段,则尝试失败。如果返回曲线 1,则成功。你有一个封闭的区域。
    • 记住所有成功的尝试
    • 对曲线 1 的所有段重复此操作
    • 对所有其他曲线重复此操作,检查所有找到的区域与已找到的区域。两个相同的相邻段足以认为面积相等。

如何找到路口的方向。

当段 p(p1,p2) 穿过段 q(q1,q2) 时,我们可以计算向量 pXq 的向量乘法。我们只对它的 Z 坐标的符号感兴趣——那是在我们的平面之外。如果是+,q从左到右穿过p。如果是-,q从右到左穿过p。

向量乘法的Z坐标在这里算作矩阵的行列式:

0         0          1
p2x-p1x   p2y-p1y    0
q2x-q1x   q2y-q1y    0

(当然也可以写得更简单,但这是一个很好的记忆技巧)

当然,如果您要更改左侧的所有权限,那么整个算法不会真正发生任何变化。

【讨论】:

  • “检查所有段对”虽然不是很有效。计算多边形的交点可以在 polylog 线性时间内完成,因此实际上计算所有成对的交点可能会更好
  • @NiklasB。当然,您可以通过使用不同的过滤器来大大缩短寻找交叉点的时间。但那部分是不太重要的部分。我什至不知道,也许提问者已经有了交点。
  • @NiklasB。我们的任务是给出一个有用的想法,具体的工作是问题的作者本人。
  • 该算法是否处理多个多边形共享一个线段或部分线段的情况?
  • @user3290797 是的。但是,如果他们不能拥有部分细分市场。多边形的生成是有限的,因此如果它们共享 2 个相邻线段,则多边形是相等的。
【解决方案2】:

您的问题称为地图叠加问题。可以在O(n*log(n)+k*log(k))时间内求解,其中n为线段数,k为线段交点数。

首先你需要将你的多边形表示为doubly connected edge list,不同的面对应不同多边形的内部。

然后使用Bentley–Ottmann algorithm 查找所有线段交点并重建边列表。请参阅:Computing the Overlay of Two SubdivisionsSubdivision representation and map overlay

最后,遍历边缘列表中的每个循环并收集该循环半边的面。每组面将代表一个不同的重叠区域。

另请参阅:Shapefile Overlay Using a Doubly-Connected Edge List

【讨论】:

    猜你喜欢
    • 2012-03-25
    • 2012-01-19
    • 1970-01-01
    • 2015-03-12
    • 2011-12-19
    • 2011-01-28
    • 1970-01-01
    • 2012-08-04
    • 1970-01-01
    相关资源
    最近更新 更多