N个矩形的交集

15
我正在寻找一种算法来解决这个问题:
给定笛卡尔坐标系上的N个矩形,找出这些矩形的交集是否为空。每个矩形可以位于任意方向(不必与Ox和Oy平行)。
你有什么建议来解决这个问题吗? :) 我可以考虑测试每对矩形之间的交集。但是,它的时间复杂度为O(N*N),而且相当慢 :(

相关:https://dev59.com/kXVD5IYBdhLWcg3wBWzd - Alexandre C.
6个回答

19

摘要

可以使用按矩形最小X值排序的算法,或将矩形存储在R树中并搜索它。

直接方法(带排序)

我们将low_x()表示为矩形的最小(最左边)X值,将high_x()表示为矩形的最高(最右边)X值。

算法:

Sort the rectangles according to low_x().                   # O(n log n)

For each rectangle in sorted array:                         # O(n)
    Finds its highest X point.                              # O(1)
    Compare it with all rectangles whose low_x() is smaller # O(log n)
        than this.high(x)

复杂度分析

对于均匀分布的矩形,这应该可以在 O(n log n) 的时间内完成。

最坏情况下是O(n^2),例如当矩形不重叠但彼此相邻时。在这种情况下,需要将算法推广到具有 low_y()high_y()

数据结构方法:R-Trees

R-trees demonstration

R树(一种空间泛化的B树)是存储地理空间数据最好的方法之一,对于这个问题非常有用。只需将矩形存储在R树中,您就可以使用简单的O(n log n)复杂度找到交集。(每次搜索n个,每个需要log n时间)。


它的时间复杂度是O(n^2)。最后一步不是O(log n)。反例:矩形集合{ [k, 2n-k]×[0, 1] | k ∈ {0, ..., n-1} } - Yakov Galka
亚当,记住“每个矩形可以位于任何方向(不一定要将其边缘平行于Ox和Oy)”。 - ariel
我不确定 - 让我思考一会儿。 - Adam Matan
@ybungalobill - [k, 2n-k]×[k, 2n-k]仅仅是点矩形吗? - Adam Matan
1
是的,这是对错误问题的答案。累积n个轴对齐框的交集是微不足道的,您不需要任何非微不足道的数据结构。只需砍掉盒子的轴向切片即可。 - Don Hatch
显示剩余5条评论

4
观察1:给定一个多边形A和一个矩形B,交集A ∩ B可以通过与B的每条边相应的半平面的4个交点来计算。
观察2:从凸多边形中切割出一个半平面会得到一个凸多边形。第一个矩形是一个凸多边形。这个操作最多可以增加1个顶点。
观察3:凸多边形的顶点到一条直线的有符号距离是单峰函数。
以下是算法草图:
在CCW顺序的平衡二叉树中维护当前部分交集D。
当切割由线L定义的半平面时,找到D中与L相交的两条边。通过利用有符号距离对L的单峰性进行一些巧妙的二进制或三进制搜索,可以在对数时间内完成。(这是我不太记得的部分)。从D中删除L的一侧的所有顶点,并将交点插入D中。
对于所有矩形的所有边缘L重复此过程。

2

没错,Klee测度基本上是这个问题的概括,并完美地涵盖了它,展示了一个最优算法。 - ldog
我正在寻找交集。我认为Klee测度是关于这些矩形的并集吗? - Chan Le
这个答案很有趣,但它不清楚如何应用。也许关于交集的问题可以转化为关于并集的问题,通过某种方式取补集? - Don Hatch

1

这里存在一个问题,就是使用n个矩形可以创建n^2个边界交叉点...(想象一下不同厚度的加号)。 - Yakov Galka

0

由于矩形不能平行于坐标轴,将问题转化为已经解决的问题:计算矩形边界的交点。

  • 构建一个包含所有边界及其所属矩形的集合S;您将得到一组元组,格式为((x_start,y_start),(x_end,y_end),r_n),其中r_n是相应矩形的ID
  • 现在使用扫描线算法来查找这些线的交点

扫描线在S中的每个x坐标处停止,即所有起始值和所有结束值。对于每个新的起始坐标,将相应的线放入临时集合I中。对于每个新的结束坐标,从I中删除相应的线。

除了向I添加新线之外,还可以检查每条新线是否与当前在I中的某条线相交。如果它们相交,则相应的矩形也会相交。

您可以在此处找到有关此算法的详细说明。

运行时间为O(n*log(n) + c*log(n)),其中c是I中线的交点数。


1
问题在于 c=n^2 是有可能的。请参见我对@MarcoS答案的评论。 - Yakov Galka
@ybunga:没错,但这是根本问题的本质。如果解集的最大大小为n^2,则查找此集合的算法也必须具有O(n^2)的最坏运行时间。我建议的算法具有其运行时间能够适应解决方案复杂性的优点。 - Philip

-1

从集合中选择最小的矩形(或任何矩形),并遍历它内部的每个点。如果其中一个点也存在于所有其他矩形中,则交集不为空。如果所有点都没有被其他矩形占据,则交集为空。


如果 R1 不与 R2 和 R3 相交,这并不意味着 R2 和 R3 之间不相交。 - ariel
@ariel:但这意味着R1、R2和R3不相交。但是这仍然是低效的,我们可以根据Adam提到的矩形的边缘(顶部/底部或左侧/右侧)来判断。 - Gaurav Dadhania
你如何确定“其中的每个点”?:) 因为一个区域内有无限多个点。 - Chan Le

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接