多边形分解算法

时间:2014-02-15 14:41:57

标签: algorithm polygon intersection polygons convex-polygon

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

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

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

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

2 个答案:

答案 0 :(得分: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,因为你可以沿着第一条交叉曲线到达两侧。
    • 对于正确的尝试,只做左转,对于左尝试,只做右转。
    • 如果您到达没有正确方向段的点,则尝试失败。如果返回曲线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

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

当然,如果你要改变左派的所有权利,那么算法整体上没有任何改变。

答案 1 :(得分:1)

您的问题称为地图叠加问题。它可以在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