在O(nlogm)时间内具有全部n个顶点的平面中找到m个多边形集合中的两个凸多边形的交集
答案 0 :(得分:2)
以下是O(n * log m)
解决方案:
让我们检查两个多边形是否真正相交(而不是一个是多边形)
包含在另一个内)。在这种情况下,我们可以使用标准算法
检查任意组中是否存在一对交叉段
细分市场有一个众所周知的O(n * log n)
扫描线解决方案
对于这个问题(我稍后将展示如何为此O(n * log m)
特别的问题)。我们感兴趣的一组细分只是一组
给定多边形的所有边缘。如果找到了一个交叉点,我们就完成了。
否则,我们必须检查一个多边形是否包含在另一个多边形中。我们
将再次使用扫描线。事件应按其x坐标排序
有两种类型的事件:多边形的边缘已经开始,边缘有
结束。让我们迭代所有事件并维护一个有序集合
(使用平衡二叉搜索树)(边缘应按其对照进行比较
y坐标,它们的相对顺序永远不会改变,因为它们都没有相交)
所有已开始但未结束的边(第一个类型事件将一个边添加到
集合,第二种类型删除一个)。我声称包含一个多边形
在另一个内,当且仅在某一点上,在以下的序列中存在以下序列
集合:A B B A,其中A是一个多边形的边,B是
的边
另一个。要检查这种情况是否发生,这就足够了
查看相邻的新插入/新删除的元素
每次插入/删除后。
到目前为止,它看起来像O(n * log n)
。
现在让我们实现O(n * log m)
时间复杂度。迭代了
1和2中的事件。维护集合已经O(n * log m)
因为一次最多只有O(m)
个元素(不超过
每个多边形的两条边)。所以唯一剩下的部分是全部排序
边缘乘x坐标。这里的想法非常简单:对于凸多边形,
可以在O(k)
时间内生成其边缘的排序列表,其中
k
是顶点的数量(我们可以在2中从左到右遍历它
方向并获得两个可以在线性时间内合并的排序列表。所以
现在我们有m
个排序列表,总共不超过n
个元素。合并
它们在O(n * log m)
时间内使用堆进入一个排序列表是一个标准
问题也是。就是这样。