当前位置: 首页 > 知识库问答 >
问题:

在现有的、不重叠的矩形之间拟合一个矩形

叶炜
2023-03-14

我有一个问题,也许可以用计算机屏幕上的窗口来最好地说明:创建另一个尽可能大的窗口,不与任何现有窗口重叠。

换句话说:在有限表面(一张纸或一块屏幕)上给定一组N个矩形,找到可以安装在这些矩形之间的最大矩形。(坐标可以是任意的,因此位图在这里不是可行的解决方案。

下面的照片显示了三个矩形(黑色)和最大的矩形(红色)。

http://www.irstafoto.se/blogmtrl/rectangle-illustration.jpg

我为此编写了一个简单的算法,它考虑了矩形使用的所有x和y坐标对。不幸的是,它是O(N^5),因为在最坏的情况下,每个候选矩形必须与每隔一个矩形进行重叠检查。

还有更好的吗?



       max_area = 0;
       max_rect = nil

       xc = all rectangle x-coordinates [x1, ..., x6] in picture)
       yc = all rectangle y-coordinates (y1, ..., y6] in picture)
       xc = [0] + xc + [W]; /* W is width of area */
       yc = [0] + yc + [H]; /* H is height of area */

       sort(xc);
       sort(yc);

       for each x0 in xc
           for each x1 > x0 in xc
               for each y0 in yc
               for each y1 > y0 in yc
                       r = rect(x0,y0,x1,y1)
                       if (area(r) > max_area and !overlapping(r))
                           max_area = area(r)
                           max_rect = r

共有2个答案

颜楚青
2023-03-14

半四叉树方法怎么样?您可以创建一个具有9个属性的节点,矩形本身,4个矩形,其区域位于节点当前矩形的北部、南部、东部和西部;最后4个节点,每个节点在相应的区域都有子树。节点类看起来像这样:

class node 
{
    public var nr:Rectangle;
    public var sr:Rectangle;
    public var wr:Rectangle;
    public var er:Rectangle;

    public var nn:node = null;
    public var sn:node = null;
    public var wn:node = null;
    public var en:node = null;

    public var rect:Rectangle;
}

创建新节点时,应仅使用包含当前矩形边的线剪裁边界区域。这不是典型的四叉树。在这里,子节点的区域可能重叠。

两个更重要的行动。首先html" target="_blank">添加矩形。从第一个实心矩形开始,创建一个节点,然后为每个剩余的矩形将它们添加到树中。要将矩形添加到节点,您应该检查它是否与其任何区域重叠。如果是这样,请将其剪辑到该区域并将其向下推到该节点。如果节点为空(或空),请创建一个新节点。

终于找到一个最大的矩形。这是从根节点以递归方式完成的。您应该从覆盖所有4个区域的矩形中获得最大的矩形。这很容易,因为您已经将它们作为节点的属性。但是,有一个技巧 - 如果此区域中有一个子节点,则应使用此节点最大的矩形(这是递归)。

云骏奇
2023-03-14

我的建议是:

独立地对X和Y进行排序,以便您可以将所有角坐标映射到范围[0,2N]内的整数索引。

在缩小坐标中空间被矩形占据的二进制图像中填充黑色。图像大小将为(2N1)x(2N1)。

找到可以放置在白色区域中的最大矩形。这可以按与图像区域成比例的时间完成。(请参阅文章“基于矩形列表的对象描述符:方法和算法”。

然后对于每个最大矩形,计算实际面积,给定真实坐标,并保持最大

这应该是一个完整的O(N²)过程。

 类似资料:
  • 我已经在这里呆了2-3周了,我仍然无法进行适当的碰撞检测。我用矩形创建了一个迷宫。我希望我的对象(在矩形中)每当我的对象与任何墙壁碰撞时停止,并能够移动到任何地方(或滑下墙壁)。我的墙壁(矩形)具有负坐标,如下所示: 我目前正在使用SO中发现的重叠方法。以下是我的CollisionManager类中的方法: 我有一个功能可以保存对象所做的所有位置移动。因此,当发生碰撞时,对象会恢复到最后一次移动之

  • 我试图在现有画布中的特定框顶部添加一些红色矩形,与预期结果图像完全相同,但它们根本没有出现,因为我的代码显示了部署应用程序时当前不希望出现的结果。我的代码是在顶行和底行分别创建4个矩形,但我只想将其添加到框2-6的顶部,但我知道需要为框1顶部的红色矩形添加额外的代码 activity_main.xml MainActivity.java

  • 我试图找出两个矩形是否相互重叠。我将下面的矩形表示为< code>[x1,x2] x [y1,y2] 我只需要一个伪代码,我可以实现它来查找矩形是否彼此重叠。

  • 在上面的图片中,我展示了两个矩形 矩形1,其x可以从-900到13700不等,Y可以从-600到6458 矩形2,其坐标X可以从0到3000变化,而y可以从0到2000变化 同样:矩形2的起点位于左上角位置(0,0),而矩形1的起点位于左上角位置(宽度/2,高度/2)。 我需要做的是:使用缩放或平移将矩形1的点转换为矩形2的点。 那么,为了将矩形1的坐标转换为矩形2的坐标,< code>x和< c

  • 在我的自上而下游戏中,当我的玩家通过婴儿床时,我该如何让他发生碰撞?我用的是交叉矩形。 这是我的密码 更新方法 在渲染方法中 这是完整的代码 谁能告诉我矩形碰撞检测的正确实现是什么?没有重叠,我是这个框架的新手。致谢和预付款:)

  • 我有一个非常大的矩形(100,000x100,000),我试图在上面随机放置许多不同大小的圆。我目前的解决方案是将以前使用的所有坐标对存储在一个地图中,然后随机生成一个新的对,并检查它是否存在于地图中。 因为我生成了很多坐标,所以这个方法会变得有点慢。有没有一个更好,最重要的是更快的方法来得到矩形上的随机坐标,也许也有一个方法来得到它们而不是圆重叠?