Fitting a rectangle inbetween existing, non-overlapping rectangles

谁说胖子不能爱 提交于 2019-12-11 11:58:36

问题


I have a problem that can perhaps best be illustrated with windows on a computer screen: create another window, as large as possible, not overlapping any of the existing windows.

In other words: given a set of N rectangles on a finite surface (a sheet of paper, or a screen), find the largest rectangle that can be fitted inbetween these rectangles. (Coordinates can be arbitrary, so a bitmap is not a viable solution here.)

The following photo shows three rectangles (in black) and the largest rectangle that can be fitted (in red).

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

I have written a naive algorithm for this which considers all pairs of x- and y-coordinates used by the rectangles. It is, unfortunately, O(N^5) because in the worst case each rectangle candidate must be checked against every other rectangle for overlapping.

Is there anything better?



       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


回答1:


My suggestion:

Sort on X and Y independently so that you can map all corner coordinates to an integer index in range [0,2N].

Fill a binary image with black where space is occupied by a rectangle in the reduced coordinates. The image size will be (2N+1)x(2N+1).

Find the maximal rectangles that you can place in the white area. This can be done in time proportional to the image area. (See the article "Object descriptors based on a list of rectangles: method and algorithm".)

Then for every maximal rectangle, compute the actual area, given the true coordinates, and keep the largest

This should be an overall O(N²) procedure.




回答2:


What about semi quad-tree approach? You could create a node with 9 properties, the rectangle itself, 4 rectangles with area that is available north, south, east and west of the node's current rectangle; and finally 4 nodes each having subtree in corresponding areas. Node class would look something like this:

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;
}

When creating a new node you should just clip bounding area with lines containing sides of current rectangle. This is not a typical quad-tree. Here subnode's areas may overlap.

Two more essential actions. First adding the rectangle. Starting with first solid rectangle you create a node and then for each of remaining rectangles you add them to the tree. To add rectangle to node you should check if it overlaps any of its areas. If so, clip it to the area and push it down to that node. If node is empty (or null) create a new one.

Finally finding a largest rectangle. This is done recursively starting at the root node. You should get the largest rectangle from those that cover all 4 areas. It is quite easy as you already have them as properties of your node. There is one trick however - if there is a subnode in this area you should use this nodes largest rect (here's the recursion).



来源:https://stackoverflow.com/questions/32773224/fitting-a-rectangle-inbetween-existing-non-overlapping-rectangles

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!