【问题标题】:Looking for a non "brute force" algorithm to remove intersecting areas of a collection of Rects寻找一种非“蛮力”算法来删除矩形集合的相交区域
【发布时间】:2012-03-07 09:31:26
【问题描述】:

我有一个 n 大小的 Rect 集合,其中大部分相互交叉。我想删除交叉点并将相交的矩形减少为更小的非相交矩形。

我可以很容易地暴力破解解决方案,但我正在寻找一种有效的算法。

这是一个可视化:

原文:

已处理:

理想情况下,方法签名应如下所示:

public static List<RectF> resolveIntersection(List<RectF> rects);

输出将大于或等于输入,其中输出解析上述视觉表示。

【问题讨论】:

  • 红色矩形占用的空间本可以被绿色或橙色矩形占用(使它们更长...)?
  • 我随意分割了那个矩形。
  • 事实证明这确实是我想要的:google-maps-utility-library-v3.googlecode.com/svn/trunk/… 我可能应该要求解决实际问题,而不是解决我在实施过程中创建的问题。

标签: algorithm polygon intersection rect orthogonal


【解决方案1】:

你说的是包装问题,看看wikipedia

参考this文章,描述了一种将矩形打包成矩形的算法

这是来自文章:

本文介绍了一种快速算法,可将一系列不同宽度和高度的矩形打包成一个单独的封闭矩形,不发生重叠,并且可以最大限度地减少封闭矩形中浪费的空间量。

【讨论】:

  • 你确定吗?你如何通过使用矩形包装将重叠的矩形分解成更小的非重叠?在我看来,解决方案可以基于扫描线算法:en.wikipedia.org/wiki/Sweep_line_algorithm
  • @Timo 它是包装问题的一种变体,我已经添加了介绍的前几行。
  • @Timo 虽然,我以前从未听说过扫描线算法,但从我读到的内容听起来很有趣,它也可能是一个好方法。
  • 这不是在另一个矩形内,封闭的边界是由所有矩形的联合组成的。扫描线似乎更近了。
【解决方案2】:

扫描线算法擅长处理二维宇宙中的交叉点。我的意思是考虑一条从矩形边缘向下移动到下一个矩形边缘的水平线。这条线碰到许多矩形,形成所谓的活动列表。活动列表在每次移动时都会保持更新。

通过研究沿水平线的横坐标范围,您可以检测到重叠。

仔细研究所有配置应该可以让您在一次扫描中按照您想要的方式拆分矩形,其复杂性低于蛮力(接近 N^1.5 而不是 N^2)。

【讨论】:

  • 在上面的例子中,这可能比暴力破解稍微高效一些,但我认为这是我能做到的最好的。谢谢。
  • 已知矩形相交问题可以在最优时间 O(N Log(N) + K) 内求解,其中 K 是实际相交数,例如使用区间树。作为扫线的替代方案,已经发布了分治算法。
【解决方案3】:

这是我过去解决的一个问题。首先使用其中一条边的 x 或 y 值对矩形进行排序。假设您在 y 方向订购并使用顶部边缘。您的示例中最上面的矩形按排序顺序排列在第一位。对于每个矩形,您都知道它在 y 方向上的大小。

现在,对于排序列表中的每个条目(称为当前条目,它对应一个矩形),您在列表中向前搜索,直到找到大于当前条目 + 相应矩形大小的条目。 (称之为停止入口)

排序列表中当前条目和此停止条目之间的任何条目都将是潜在的交叉点。只需检查矩形 x 范围是否相交。

选择在 x 或 y 方向排序时,最好选择更大的维度,因为这意味着平均交叉点更少,因此检查更少。

这是一个例子。矩形定义为 R(x1,x2,y1,y2),其中 x1 是左侧,x2 是右侧,y1 是顶部,y2 是底部

rectangle 1 (1,5,0,4) 
rectangle 2 (7,9,6,8)
rectangle 3 (2,4,2,3)
rectangle 4 (3,6,3,7)
rectangle 5 (3,6,9,15)

按照y1排序给出

#              y1  size
rectangle 1     0   4
rectangle 3     2   3
rectangle 4     3   4
rectangle 2     6   2
rectangle 5     9   6

所以,矩形 1 的 y1 + size = 0 + 4 = 4 意味着它可能与矩形 3(y1 值 = 3 4)...在 2 之后无需检查列表中的任何矩形

矩形 3 的 y2 + 大小 = 2 + 3 = 5 意味着它可能与矩形 4 相交(y1 值 = 3 5)无需检查矩形中的任何矩形2 之后的列表

矩形 4 的 y2 + size = 3 + 4 = 7 暗示它可能与矩形 2 相交(y1 值 = 6 7)

当然,对于大量的矩形,您通常只需检查一小部分可能的交叉对。

【讨论】:

  • 一项改进:要决定使用哪个维度进行排序,您可以查看该维度中的值范围除以该维度中的平均矩形大小。在上面的示例中,平均 y 大小为 19/5,而平均 x 大小为 15/5,因此您会期望(没有其他知识)这些是 y 方向上的更多交叉点(矩形 y 大小平均更大比 x 尺寸,因此它们相交的机会更大)。如果您正在查看数千个矩形,此选择可能会产生很大的不同。
猜你喜欢
  • 2013-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-02
  • 2020-04-03
  • 2016-04-05
  • 2020-07-26
  • 2018-05-24
相关资源
最近更新 更多