【问题标题】:Lay out rectangles avoiding collisions (algorithm help)布置矩形以避免碰撞(算法帮助)
【发布时间】:2011-08-30 23:24:48
【问题描述】:

我有一个(大)水平滚动视图,还有一堆我想在上面放置的矩形。每个矩形都有一个所需的水平位置,但如果需要,它可以从那个位置变化到一定的量(一个常数,K)。矩形不得重叠。矩形的垂直位置是任意的(当然受限于视图的高度)。

理想情况下,我希望矩形的大小是可变的……我想如果这不可能,我可以使大小仅在一维上变化。

现在,这种布局会出现不可能的情况:由于只有一定的垂直空间,并且它们只能将 K 个像素从理想的水平方向移开,因此可能并非所有矩形都能够绘制出来。为了解决这个问题,每个矩形都有一个优先级(P),优先级较低的应该首先被忽略。 (您可以假设这是明确的,并且您始终可以判断任意两个矩形中哪个具有更高的优先级。)

我追求的是概念算法的东西,但如果你需要细节,这将在 iPad 上运行,并且需要考虑几千个(>1000 但

我见过像this 这样的算法,它可以实现不相交的技巧,但对于每个项目只允许移动一定数量的想法并不相同。显然,如果没有后一个约束,您可以显示所有项目,所以我还需要一些方法来知道在什么时候不再显示矩形。

如果解决所描述的问题太困难,我欢迎提出更务实的想法。如果所有其他方法都失败了,我总是可以按优先顺序做一些事情,如果可以的话,将每个项目渲染到所需的位置,如果不能,则尝试垂直移动它,如果仍然不能,则将其水平移动到允许的限制,在继续下一个之前。优先级排序意味着可能会找到一个次优的解决方案,但它会偏重于最重要的项目。

【问题讨论】:

  • 一两张图片可以改善这个问题。
  • 图像已创建。抱歉,很难描述:)

标签: algorithm layout


【解决方案1】:

这是我认为可以做到的一种方式。

第 1 步是找出可以放置新黄色矩形的所有位置。不失一般性,我们可以将其存储为矩形左上角所有可能的 X-Y 位置的列表。自然地,对于这样一个巨大的起始区域,列表将包含数百万个条目,所以为了节省空间,我们将这个列表存储为一组矩形区域的形式。

例如,如果我们的屏幕有从 X=0 到 X=2999(含)和从 Y=0 到 Y=999(含)的像素,并且我们的新矩形的宽度为 300 像素,高度为 150 像素,则左上角我们的新矩形可以出现在从 (X,Y) = (0, 0) 到 (2699, 849) 的任意位置。让我们将其存储为四元组,[0, 0, 2699, 849]。

现在,当我们将每个现有的(红色)矩形放到屏幕上时,其中一些可能性就被排除了,因为它们会导致新的(黄色)矩形与它们重叠。例如,如果有一个红色矩形 [1100, 200, 1199, 299],那么我们的黄色矩形的左上角不能在 (X,Y) = (801, 51) 到 (1199, 299) 的任何位置包括在内。

因此,将 [0, 0, 2699, 849] 替换为覆盖相同区域但留下间隙的四个矩形区域。有很多方法可以做到这一点,但这里有一种:[0, 0, 1199, 50], [1200, 0, 299, 2699], [0, 51, 800, 849], [801, 300, 2699, 849 ].

继续在屏幕上添加更多红色矩形。每次添加一个,从列表中减去更多的可能性(这通常会导致列表包含更多、更小的“安全区域”)。 (对于有 1000 多个矩形的全屏来说,这可能非常耗时;相反,如果您只从您提到的 [X-K, 0, X+K, H] 空间开始,那么 1000 个中相对较少+ 将与此重叠,计算速度会更快。)这段代码应该非常小心地编写并进行大量单元测试,因为栅栏错误会比比皆是。

最终结果是屏幕上可以放置新黄色矩形左上角的可能位置的完整列表,以矩形区域列表的形式表示。

第 2 步:查看此列表并选择最理想的位置。任何实际与理想垂直线相交的矩形区域都将优先考虑。但也有可能没有。在这种情况下,您可以从位于理想线左侧的区域和位于右侧的区域中选择最可取的选项。提示:在每种情况下只需要考虑每个区域的一个角(右侧区域的左上角,左侧区域的右上角)。

【讨论】:

  • 对不起,我直到现在才回复。碰巧的是,我最后采用了一种更简单的布局方法。这个答案绝对是完成我最初要求的最简单的方法:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-03
  • 2023-03-16
  • 2014-03-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多