我有许多多边形,每个多边形都表示为一个点列表。我正在寻找一种快速算法来遍历多边形列表并且不会覆盖所有交叉边缘,直到没有交叉边缘为止。
当前版本的Psudocode:
While True:
For each pair of polygons:
for edge1 in first_polygon:
for edge2 in second_polygon:
if edges_cross(edge1,edge2): # Uses a line segment intersection test
uncross_edges(first_polygon,second_polygon,edge1,edge2)
If no edges have been uncrossed:
break
通过用递归替换while循环可以改善这一点。但是,它在性能方面仍然相当差。
下面是解开*的简单示例。实际上,每个多边形(大约10-500)会有大量的多边形和相当数量的点。红线表示哪两条边是未交叉的。结果应始终是一系列平面图,但不确定是否有多个有效结果或只有一个。
编辑:这次我首先添加了行,然后添加了点,并使用了更复杂的形状。假装分数是固定的。
答案 0 :(得分:1)
首先,让我们说明你想要的东西(如果我做对了)。假设您有两个多边形,其中一个边缘(a, b)
与另一个边缘(s, r)
相交。这些多边形也具有顺时针方向,因此您知道b
之后的下一个顶点和r
之后的下一个顶点。由于边缘交叉,您将它们都删除,并添加四个新的边缘。您添加的新内容包括:(a, r)
,(r, next(b))
; (s, b)
,(b, next(r))
。所以你又有两个多边形。如下图所示。请注意,通过最初只删除两条边(每个多边形中有一条边),所有交叉点都已解析。
每次迭代加速O(n^2)
的简单实现并不容易,每个多边形500点是一个非常小的担心。如果您决定需要改善这段时间,我最初的建议是以一种聪明的方式使用Bentley-Otmann algorithm。智能方法涉及运行算法,然后当您找到交叉点时,执行上述过程以消除交集,然后更新指导算法的事件。希望可以更新要处理的事件,而不会使算法在这种情况下无用,但我没有证明这一点。
答案 1 :(得分:0)
您似乎希望最终得到一个嵌入的平面多边形,其顶点恰好是一个给定的点集合。点上所需的“顺序”是绕过多边形边界并按照它们出现的顺序枚举顶点所得到的。
对于给定的点集合,一般会有多个具有此属性的嵌入多边形;例如,请考虑以下要点列表:
(-1,-1), (0,0), (1,0), (1,1), (0,1)
此列表定义符合条件的多边形(如果我理解正确的话)。但是这个列表的以下排序也是如此:
(-1,-1), (1,0), (0,0), (1,1), (0,1)
这是一种可行的算法(我不知道快速)。
首先,按x级坐标(例如快速排序)按升序对点进行排序(调用此列表L)。
其次,找到凸包(例如用快速船体);凸包的边界将包含排序列表L中最左边和最右边的点(称为L [1]和L [n]);设S是L [1]和L [n]之间边界上的点的子集。
你想要的列表是S在它出现在L中的顺序(它也将是它出现在凸包边界的顺序),其次是其他元素LS,它们在L中出现的顺序相反。
前两个操作通常应该花费时间O(n log n)(最差情况为O(n ^ 2));最后需要时间O(n)。你得到的多边形将是凸包的下边界(从左到右,比方说),以及从右到左上方的“之字形”中的其余点。