【问题标题】:optimal negative space between rectangles algorithm?矩形算法之间的最佳负空间?
【发布时间】:2011-02-14 02:11:11
【问题描述】:

给定较大矩形 R 内的矩形 r[ ],是否有一个最佳的快速算法来确定填充 r[ ] 之间的“negative space”的矩形的最小数量?

例如,给定紫色矩形内的这三个蓝色矩形:

我怎样才能快速确定下面绿色的矩形列表(这可能不是最佳配置,因此我的帖子):

【问题讨论】:

  • 它看起来像您示例中的算法从上到下扫描以寻找障碍物。当它找到一个时,它会完成当前的填充矩形并开始两个新的。当它找到障碍物的尽头时,它会完成当前相邻的填充矩形并开始一个更大尺寸的新填充矩形。
  • 这可能与更一般的问题有关,给定一组矩形,找到精确覆盖这些矩形的最小数量的矩形。我不确定该问题存在哪些算法,但如果有解决该问题的有效方法,它应该为您提供解决该问题的有效解决方案。

标签: algorithm language-agnostic geometry


【解决方案1】:

oosterwal 所描述的是梯形分解的一种特殊情况,这是一种在计算几何中广为人知的原语,通常用于平面细分中的点定位。它可以在时间 O(n log n) 中以合理的常数实现。

当矩形处于一般位置时,它将返回一个“矩形”,其中 #green rectangles = 3 * # blue rectangles + 1,这是最佳的。每个蓝色角的 L 形邻域必须被一个绿色线段沿一个方向或另一个方向切割(一般位置:我们不能对两个蓝色矩形使用相同的线段),所以对于每个蓝色矩形,我们添加 4 个绿色边 8 个绿色边和 4 个顶点(4 个新边加上 4 个细分),在此过程中将连接组件的数量减少 1。多面体公式的结果是多了 3 个面(矩形):

V - E + F = 1 + # 个连通分量。


例子:

 0123456789abc
0+-----------+
1|           |
2|  +--+     |
3|  |R | +-+ |
4|  +--+ |S| |
5|       | | |
6| +--+  | | |
7| |T |  +-+ |
8| +--+      |
9+-----------+

我们正在运行从上到下的扫描线。事件是

# (y, whichside, xmin, xmax)
(2, top, 3, 6)  # R
(3, top, 8, a)  # S
(4, bot, 3, 6)  # R
(6, top, 2, 5)  # T
(7, bot, 8, a)  # S
(8, bot, 2, 5)  # T

我们建立了一个按 x 排序的二叉搜索树,其中包含部分构造的绿色矩形。我会把它写成一个列表。

# (xmin, xmax, ymin)
(0, c, 0)

现在我们开始处理事件。首先是 (2, top, 3, 6)。我们发现它嵌套在迄今为止唯一的绿色矩形内,(xmin=0, xmax=c, ymin=0, ymax=2)。 (只要蓝色矩形不相交,蓝色区间总是嵌套。)我们开始两个新的绿色矩形,在蓝色矩形的每一边一个,搜索树包含

(0, 3, 2) (6, c, 2)

现在我们处理 (3, top, 8, a)。区间 (8, a) 嵌套在 (6, c) 中,所以我们完成另一个矩形 (xmin=6, xmax=c, ymin=2, ymax=3) 并再开始两个:

(0, 3, 2) (6, 8, 3) (a, c, 3)

现在我们处理 (4, bot, 3, 6)。这结束了左右两侧的绿色矩形,(xmin=0, xmax=3, ymin=2, ymax=4) 和 (xmin=6, xmax=8, ymin=3, ymax=4)。搜索树是

(0, 8, 4) (a, c, 3)

我认为到此为止,事情应该很清楚了。这是完成的矩形:

 0123456789abc
0+-----------+
1|           |
2+--+--+-----|
3|  |R |-+-+-|
4+--+--+-|S| |
5|       | | |
6+-+--+--+ | |
7| |T +--+-+-+
8+-+--+------+
9+-----------+

关于处理退化的说明:将底部事件放在顶部事件之前,具有相同的 y 坐标,并抑制面积为零的矩形。一般来说,仍然会有“不必要的”矩形,更复杂的事件处理器可以避免(通过一次处理给定 y 坐标处的所有事件)。

【讨论】:

  • 您能详细说明一下吗?这看起来真的很酷,我很想看到更多关于它的细节。
  • 正如 oosterwal 所说,您可以通过从上到下对蓝色水平线段进行排序和处理来执行平面扫描。当您遇到蓝色顶部时,终止其上方的绿色矩形并再开始两个。当您遇到蓝底时,终止左右的绿色矩形并开始一个新的。这些操作中的每一个都是 O(log n),二叉树按 x 坐标的顺序存储活动的绿色矩形。处理退化的情况虽然有点痛苦......
  • 好吧,说#连通分量总是减1有点草率。但是,它总是从开始的#蓝色矩形+1到结束的1,所以数学仍然作品;我们只需要摊销。
  • 我会从一些高级伪代码中受益...解析这个答案很困难。
  • 明白了——很好的解释。谢谢你。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2011-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多