我正在寻找一种算法来解决这个问题:
在笛卡尔坐标上给定N个矩形,找出这些矩形的交点是否为空。每个矩形可以位于任何方向(不必使其边缘平行于Ox和Oy)
您有什么建议可以解决这个问题吗? :)我可以考虑测试每个矩形对的交集。但是,它是O(N * N)而且很慢:(
答案 0 :(得分:18)
根据矩形的最小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(B-trees的空间概括)是存储地理空间数据的最佳方式之一,在此问题中非常有用。只需将矩形存储在R树中,您就可以发现具有简单O(n log n)
复杂度的交叉点。 (n
次搜索,每次log n
次。
答案 1 :(得分:3)
观察1:给定多边形A和矩形B,可以通过与对应于B的每个边缘的半平面的4个交点来计算交点A∩B。
观察2:从凸多边形切割半平面为您提供凸多边形。第一个矩形是凸多边形。此操作最多每1增加一次顶点数。
观察3:凸多边形顶点与直线的符号距离是单峰函数。
以下是该算法的草图:
以CCW顺序在平衡二叉树中维护当前部分交叉点D.
当切割由线L定义的半平面时,找到D中与L相交的两条边。这可以通过一些巧妙的二元或三元搜索在对数时间内完成,利用与L的有符号距离的单峰性。这是我不完全记得的部分。)从D中删除L一侧的所有顶点,并将交点插入D。
对所有矩形的所有边L重复。
答案 2 :(得分:2)
这似乎是Klee措施的一个很好的应用。基本上,如果你阅读http://en.wikipedia.org/wiki/Klee%27s_measure_problem,那么在O(n log n)的直线交点处可以找到最佳算法运行时的下限。
答案 3 :(得分:1)
我认为你应该使用像sweep line algorithm这样的东西:寻找交叉点是它的应用之一。另外,请查看answers to this questions
答案 4 :(得分:0)
由于矩形不能与轴平行,因此更容易将问题转换为已经解决的问题:计算矩形的边界的交点
扫描线在S中的每个x坐标处停止,即所有起始值和所有结束值。对于每个新的起始坐标,将相应的行放在临时集I中。对于每个新的结束坐标,从I中删除相应的行。
除了向I添加新行之外,您还可以检查每个新行是否与当前在I中的一行相交。如果有,则相应的矩形也会这样做。
您可以找到此算法的详细说明here。
运行时为O(n * log(n)+ c * log(n)),其中c是I中线的交点数。
答案 5 :(得分:-1)
从集合(或任何矩形)中选择最小的矩形,并遍历其中的每个点。如果其中一个点也存在于所有其他矩形中,则交点不为空。如果所有点都没有 ALL 其他矩形,则交点为空。