Checking whether two rectangles overlap in python using two bottom left corners and top right corners

You can use a simple version of the Separating Axis Theorem to test for intersection. If the rectangles do not intersect, then at least one of the right sides will be to the left of the left side of the other rectangle (i.e. it will be a separating axis), or vice versa, or one of the top sides will be below the bottom side of the other rectange, or vice versa.

So change the test to check if it is not true that they don't intersect:

def intersects(self, other):
    return not (self.top_right.x < other.bottom_left.x or self.bottom_left.x > other.top_right.x or self.top_right.y < other.bottom_left.y or self.bottom_left.y > other.top_right.y)

This code assumes that the "top" has a greater y value than the "bottom" (y decreases down the screen), because that's how your example seems to work. If you were using the other convention then you'd just flip the signs of the y comparisons.


I recently came across this problem and today came across named tuples, so I thought I'd give it a go:

from collections import namedtuple

RECT_NAMEDTUPLE = namedtuple('RECT_NAMEDTUPLE', 'x1 x2 y1 y2')

Rect1 = RECT_NAMEDTUPLE(10,100,40,80)
Rect2 = RECT_NAMEDTUPLE(20,210,10,60)

def overlap(rec1, rec2):
  if (Rect2.x2 > Rect1.x1 and Rect2.x2 < Rect1.x2) or \
     (Rect2.x1 > Rect1.x1 and Rect2.x1 < Rect1.x2):
    x_match = True
  else:
    x_match = False
  if (Rect2.y2 > Rect1.y1 and Rect2.y2 < Rect1.y2) or \
     (Rect2.y1 > Rect1.y1 and Rect2.y1 < Rect1.y2):
    y_match = True
  else:
    y_match = False
  if x_match and y_match:
    return True
  else:
    return False

print ("Overlap found?", overlap(Rect1, Rect2))

Overlap found? True


It can also be done with Polygon from shapely (example for a rectangle with [x0,y0,x1,y1]

from shapely.geometry import Polygon
import numpy as np

rect1=np.array([0  ,0 ,3,  3])
rect2=np.array([1, 1 , 4 , 4])

def overlap2(rect1,rect2):
    p1 = Polygon([(rect1[0],rect1[1]), (rect1[1],rect1[1]),(rect1[2],rect1[3]),(rect1[2],rect1[1])])
    p2 = Polygon([(rect2[0],rect2[1]), (rect2[1],rect2[1]),(rect2[2],rect2[3]),(rect2[2],rect2[1])])
    return(p1.intersects(p2))

print(overlap2(rect1,rect2))