Search code examples
mathgeometryoverlap

Calculating the area(s) of a rectangle that aren't being overlapped


I've got two rectangles represented by structures that contain the x1, y1, x2, y2 coordinates. One rectangle can be considered the parent, another the child.

I already know how to detect if the child rectangle is within the parent rectangle; what I'm trying to figure out now is the simplest, fastest way to determine the rectangular areas within the parent that are not being overlapped by the child rectangle.

For example, consider a 100x100 parent rectangle, and a 50x50 child rectangle located exactly in the center of the parent. This would mean there would be four rectangles representing the four areas in the parent rectangle that aren't being overlapped by the child.

Of course, the child could be in the top left, top right, bottom left, bottom right corner, or a little to the left, a little to the right, etc... there might be one, two, three, or four rectangles that represent the non-overlapped areas.

I've had some ideas for implementations to figure this out, but all seem overly complex. Is there a simple, fast way to figure this out?


Solution

  • So there could be up to 4 rectangles of non-overlapped area. Let's make a list of them.

    leftrect = rightrect = toprect = bottomrect = None
    trimmedparent = duplicate(parent)
    
    if parent.x1 < child.x1:
        leftrect = duplicate(parent)
        leftrect.x2 = child.x1
        trimmedparent.x1 = child.x1
    
    if parent.x2 > child.x2:
        rightrect = duplicate(parent)
        rightrect.x1 = child.x2
        trimmedparent.x2 = child.x2
    
    if parent.y1 < child.y1:
        toprect = duplicate(trimmedparent)
        toprect.y2 = child.y1
    
    if parent.y2 > child.y2:
        bottomrect = duplicate(trimmedparent)
        bottomrect.y1 = child.y2
    

    The only tricky part is eliminating the part where e.g leftrect and toprect might intersect. I used 'trimmedparent' as an intermediate step to trim that section from toprect.