有没有有效的方法可以让我知道这个巨大的联合多边形的每条边属于哪个小多边形的边?
解决这个问题的暴力方法是将联合多边形的每条边与每个小多边形的每条边进行比较,但这将非常低效。是否有其他更有效的技术?
我的直觉告诉我扫描线算法可能会在这里有所帮助,尽管我完全不知道该如何做。
编辑:小多边形可能重叠,因此联合多边形可能包含位于小多边形边缘的点,但这些点可能不是原始多边形的顶点。
下面显示了此内容的屏幕截图:
这里是一种解决方案。
获取每条原始边。它们可以由3个东西(过)指定:
第一步是对向量进行归一化(例如,乘以标量使得x
和y
中绝对值较大的那个为1)。然后将所有的边存储到一个哈希表中,其中键是那些向量,值是具有该向量的边的数组。(如果你有很多边,你可能考虑使用interval tree来处理边。)
现在,给定组合多边形上的一条边,您可以确定它的向量,查看您的哈希表,通常只会有少量原始多边形中具有该确切向量的边,因此不难通过它们并确定哪些重叠。
请注意,虽然这种解决方案将让您相当高效地找到边沿界运行的情况,但它将错过一个多边形仅在组合多边形的一个角落处接触边界的情况。希望这对您没有影响。
旧答案:
我认为你不需要任何复杂的数据结构来处理这种情况。我假设联合顶点的坐标与原始集合中的顶点坐标相同。因此,你可以做如下操作:为输入数据创建一个顶点列表,每个顶点记录它所属的多边形。使这些顶点易于搜索:一种朴素的方法是先按一个坐标排序,然后再按另一个坐标排序。你可以用 O(log n) 的时间找到任何一个顶点。
现在,对于联合多边形的任何给定边,搜索该边的第一个顶点,然后搜索另一个顶点。取它们所属的多边形的交集,就得到了原始多边形。为加速搜索第二个顶点,你还可以向原始列表中添加连接的顶点列表,这样就不必再进行完整的搜索。
最后一个优化是预计算:只需运行上述算法,并记录每条边的结果,然后摆脱所有顶点和边表。如果你不需要预计算表,你可以过滤出在联合中没有出现的顶点。
您可以使用多边形边缘创建BSP或更具体的四叉树。对于每个边缘,请记住它在哪些多边形中使用。
对于输出多边形中的每个边缘,执行树搜索并仅检查与四叉树叶节点中的边缘重叠。
假设原始多边形中有n
条边缘,输出多边形中有m
条边缘。创建树需要O(n log n)
,搜索边缘重叠需要O(m log n)
。总体时间复杂度为O((m+n)*log n)
。
注意:如果整个边缘在两个初始多边形中都被使用,则不在输出多边形边界上。通过这种方式,您可以从四叉树中删除重复的边缘。不是必需的。
也可以采用其他方法。创建输出多边形边缘的四叉树,并搜索每个初始多边形的边缘。运行时间为O((m+n)*log m)
,速度更快。但是,使用上述方法,如果将来需要从输入多边形中提取更多信息,则可以实现此目的。