我有很多多边形,在我对所有这些多边形进行联合后,我得到一个新的大多边形。联合算法是一个黑盒子,使用我无法控制的第三方库过程,我也不希望从任何进展中提取任何信息。
对于我来说,对于那个巨大的联合多边形的每个边缘,它有哪些属于较小多边形的哪个边缘?
解决这个问题的一种强制方法是将工会化多边形的每个边缘与每个较小的多边形进行比较,但这样效率会非常低。还有其他更有效的技术吗?
我的预感告诉我sweep line algorithm可能会有所帮助,虽然我完全不知道怎么做。
编辑:小的npolygons可以重叠,因此union多边形可以包含位于小多边形边缘的点,但这些点可能不是原始多边形的顶点。
此截图如下所示:
答案 0 :(得分:3)
这是一个解决方案。
取每个原始边缘。它们可以由(超过)3个东西指定:
第一步是对矢量进行标准化(例如,乘以标量,使x
和y
的绝对值越大,为1)。然后将所有边存储到哈希中,哈希的键是那些向量,其值是带有该向量的边数组。 (如果你有批次边缘,你可以考虑使用interval tree作为边缘。)
现在给定组合多边形的边缘,你可以找出它的向量,查看你的哈希值,你通常只有原始多边形中有少量边缘的那个精确向量,所以它不是太难以通过它们并找出哪些重叠。
请注意,虽然此解决方案可以让您相当有效地找到边缘沿边界运行的情况,但它会错过多边形只是触摸一个角上组合多边形边界的情况。希望这对你没关系。
答案 1 :(得分:2)
由于原始方法由于联合中出现的新边和顶点而不起作用(参见旧的答案和注释),我们需要使用更复杂的数据结构。
这个想法是识别输入集中包含输出集边缘的边。 “包含”是指输出集边缘的两个顶点都需要位于输入集的边缘。因此,我们需要搜索输入边集,其中包含一个穿过我们正在考虑的边的两个顶点的线段。
过滤掉大量搜索边集的简单方法是使用边界框:如果我们检查的顶点不在由边的两个顶点形成的边界框内,那么我们可以排除它。主要算法是:
INPUT:输出多边形E1的边缘,以V1和V2为终点。
输出:来自输入多边形的边,其中V1和V2都位于边缘。
第二步显而易见。第一个可以看几个地方。 K-D tree(体积对象)看起来会解决问题。或者也许是R树。还要检查similar questions的stackoverflow。不幸的是,我对空间算法并不十分精通,无法提出合适的算法。
老答案:
我认为您不需要任何奇特的数据结构来处理这种情况。我假设联合中顶点的坐标与原始集中的坐标相同。因此,您可以执行以下操作:为输入数据创建顶点列表,其中每个顶点记录它所属的多边形。使这些易于搜索:一种天真的方法是首先按一个坐标,然后另一个坐标对它们进行排序。你可以在那里找到O(log n)中的任何顶点。
现在,对于union多边形的任何给定边,搜索边的第一个顶点,然后搜索另一个。获取它们所属的多边形的集合交集,然后获得原始多边形。为了加快搜索第二个顶点,您还可以将连接的顶点列表添加到原始列表中,这样就不会再次进行完整搜索。
最终的优化是预先计算:只需运行上面的算法,并记录每个边的结果,然后去掉所有的顶点和边表。如果您不需要预先计算的表,则可以过滤出未出现在联合中的顶点的原始顶点集。
答案 2 :(得分:0)
您可以使用多边形边缘制作BSP或更具体的quadtree。对于每个边缘,记住它在哪个多边形中使用。
对于输出多边形中的每条边执行树搜索,并仅检查与四叉树叶节点中的边重叠的边。
允许原始多边形中有n
条边,输出多边形中有m
条边。要创建树O(n log n)
,需要搜索边缘重叠O(m log n)
。整体O((m+n)*log n)
。
注意:如果在2个初始多边形中使用整个边,则不在输出多边形边界中。使用此功能,您可以从四叉树中删除重复的边缘。没必要。
可以通过其他方式实现。创建四叉树输出多边形边,并搜索初始多边形的每个边。运行时间为O((m+n)*log m)
,速度更快。但是使用上层方法,如果将来需要它,可以从输入多边形中提取更多信息。