【问题标题】:Identifying the original edge of a union polygon识别联合多边形的原始边
【发布时间】:2011-06-15 07:53:31
【问题描述】:

我有很多多边形,在合并所有这些多边形之后,我得到了一个新的大多边形。联合算法是一个黑盒子,使用第三方库进程,我无法控制,我也不希望从进度中提取任何信息。

有没有有效的方法让我知道,对于那个巨大的联合多边形的每条边,它的哪条属于较小多边形的哪条边?

解决这个问题的蛮力方法是将联合多边形的每个边与每个较小的多边形进行比较,但这将非常低效。还有其他更有效的技术吗?

我的直觉告诉我sweep line algorithm 可能会在这里有所帮助,尽管我完全不知道该怎么做。

编辑:小的 npolygons 可以重叠,因此联合多边形可以包含位于小多边形边缘的点,但这些点可能不是原始多边形的顶点。

截图如下:

【问题讨论】:

  • 你如何“联合”你的多边形?我的猜测是,当你进行联合时,你可以在某处存储小多边形边缘之间的关联,以及它们在大边缘中的对应关系。
  • @Fezvez,工会是我无法控制的。查看更新后的问题。

标签: algorithm geometry computational-geometry


【解决方案1】:

这是一种解决方案。

获取每个原始边缘。它们可以由 3 件事(过度)指定:

  1. 表示方向的矢量
  2. 起点
  3. 终点

第一步是对向量进行归一化(例如,乘以一个标量,使xy 的绝对值中较大的一个为1)。然后将所有边存储到一个哈希中,其键是那些向量,其值是具有该向量的边数组。 (如果您有 很多 个边,您可以考虑使用 interval tree 作为边。)

现在给定组合多边形上的一条边,您可以计算出它的向量,查看您的哈希值,通常在原始多边形中只有少量边具有该精确向量,所以它不是很难通过它们并找出哪些重叠。

请注意,虽然此解决方案可以让您相当有效地找到边缘沿边界延伸的情况,但它会遗漏多边形仅在一个角处接触组合多边形边界的情况。希望这对你没关系。

【讨论】:

  • 您所说的“错过多边形仅在一个角处接触组合多边形边界的情况”是什么意思?从我可以看到它不会,因为组合多边形上的所有边缘都会以某种方式位于原始多边形的边缘,不是吗?
  • @Graviton,取一个五边形,将其切成 4 个三角形,在一个角落相遇。所有 4 个都接触到那个角落,但这个算法只会注意到其中 2 个接触到那个点。
  • 我可以想象你提到的五边形,但是我在那个案例上运行了你的算法,但我仍然可以得到我想要的答案;这里有什么问题?
  • @Graviton:这取决于你想要什么。你会错过一些单点交叉点。但我怀疑你不在乎他们。如果你不这样做,那么解决方案会做你想要的。
【解决方案2】:

由于联合中出现了新的边和顶点(请参阅旧答案和 cmets),因此朴素的方法不起作用,我们将需要采用更复杂的数据结构。

这个想法是识别输入集中的一条边,该边包含输出集的边。 “包含”是指输出集的边的两个顶点都需要位于输入集的边上。因此,我们需要在输入边集合中搜索包含一条穿过我们正在考虑的边的两个顶点的线段的边集。

为搜索过滤掉大量边集的一种简单方法是使用边界框:如果我们检查的顶点不在由一条边的两个顶点形成的边界框内,那么我们可以排除。那么主要的算法就是:

INPUT:来自输出多边形 E1 的一条边,以 V1 和 V2 为端点。

输出:输入多边形的一条边,其中 V1 和 V2 都在边上。

  • 从边界框同时包含 V1 和 V2 的输入集中获取边集(或者换句话说,由 V1、V2 形成的边界框)
  • 暴力搜索 V1 和 V2 所在的边。

第二步很明显。第一个有几个地方可以看。 K-D tree(体积对象)看起来可以解决问题。或者也许是一个 R 树。还要检查 similar questions 的 stackoverflow。不幸的是,我不太精通空间算法,无法推荐合适的算法。


旧答案:

我认为您不需要任何花哨的数据结构来处理这种情况。我假设联合中顶点的坐标与原始集合中的坐标相同。因此,您可以执行以下操作:为您的输入数据创建一个顶点列表,其中每个顶点记录它所属的多边形。使这些易于搜索:一种天真的方法是先按一个坐标对它们进行排序,然后再按另一个坐标排序。您可以通过这种方式找到 O(log n) 中的任何顶点。

现在,对于联合多边形的任何给定边,搜索边的第一个顶点,然后搜索另一个。取它们所属多边形的集合交集,就得到了原始多边形。为了加快搜索第二个顶点的速度,您还可以在原始列表中添加一个连接顶点列表,这样您就不会再次进行完整搜索。

最后的优化是预先计算:只需运行上述算法,并记录每条边的结果,然后去掉所有的顶点和边表。如果不需要预先计算好的表格,可以针对未出现在并集的顶点过滤掉原来的顶点集。

【讨论】:

  • 不太确定这是否有效,因为当我合并所有多边形时,新的顶点(不属于原始多边形的顶点)会出现在合并多边形中。跨度>
  • 那么您可能想澄清这个问题。对于出现新顶点的情况,上面的简单解决方案是不够的。您还需要描述这些新顶点的特征:如何确定它们是否属于原始多边形?
  • 我的意思是,想象一下如果两个多边形重叠,那么两个多边形的并集将创建不在原始两个多边形顶点上的点,但这些点将位于多边形。这就是我所说的新顶点出现的意思
  • @Graviton Gotcha。对于这种情况,您将需要一个更好的数据结构来快速确定可能包含这个新顶点的边。 K-D 树似乎解决了这个问题。如果我能找到什么,我会更新答案。
【解决方案3】:

您可以使用多边形边缘制作BSP,或更具体的quadtree。对于每条边,请记住它在哪个多边形中使用。

对输出多边形中的每条边执行树搜索并检查边是否与四叉树叶节点中的边重叠。

让原始多边形中有n 边,输出多边形中有m 边。需要创建树O(n log n) 并需要搜索边缘重叠O(m log n)。总体O((m+n)*log n)

注意:如果在 2 个初始多边形中使用整条边而不是在输出多边形边界中。有了这个,您可以从四叉树中删除重复的边。没必要。

也可以换一种方式。创建输出多边形边的四叉树,并搜索初始多边形的每条边。运行时间为O((m+n)*log m),比较快。但是如果您将来需要,您可以使用上面的方法从输入多边形中提取更多信息。

【讨论】:

    猜你喜欢
    • 2020-05-26
    • 2011-10-14
    • 1970-01-01
    • 1970-01-01
    • 2013-12-07
    • 1970-01-01
    • 2011-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多