求两个矩形的交集和并集

Find the intersection and union of two rectangles

我需要求两个矩形的交集和并集的面积,以及交集面积与并集面积的比值。做这个的最好方式是什么? Picture

def intersection_over_union(a, b):
    ax1 = a['left']
    ay1 = a['top']
    aw = a['width']
    ah = a['height']
    ax2 = ax1 + aw
    ay2 = ay1 + ah

    bx1 = b['left']
    by1 = b['top']
    bw = b['width']
    bh = b['height']
    bx2 = bx1 + bw
    by2 = by1 + bh

    delta_x = max(ax1, bx1) - min(ax2, bx2)
    delta_y = max(ay1, by1) - min(ay2, by2)

    overlap = delta_x * delta_y
    union = aw * ah + bw * bh - overlap

    print(overlap, union)

    return overlap / union

假设您正在处理 AABB(轴对齐边界框),这个 class 定义了您需要的一切:

class Rect:
    def __init__(self, x, y, w, h):
        self.x = x
        self.y = y
        self.w = w
        self.h = h
    
    def bottom(self):
        return self.y + self.h
    
    def right(self):
        return self.x + self.w
    
    def area(self):
        return self.w * self.h

    def union(self, b):
        posX = min(self.x, b.x)
        posY = min(self.y, b.y)
        
        return Rect(posX, posY, max(self.right(), b.right()) - posX, max(self.bottom(), b.bottom()) - posY)
    
    def intersection(self, b):
        posX = max(self.x, b.x)
        posY = max(self.y, b.y)
        
        candidate = Rect(posX, posY, min(self.right(), b.right()) - posX, min(self.bottom(), b.bottom()) - posY)
        if candidate.w > 0 and candidate.h > 0:
            return candidate
        return Rect(0, 0, 0, 0)
    
    def ratio(self, b):
        return self.intersection(b).area() / self.union(b).area()

if __name__ == "__main__":
    assert Rect(1, 1, 1, 1).ratio(Rect(1, 1, 1, 1)) == 1
    assert round(Rect(1, 1, 2, 2).ratio(Rect(2, 2, 2, 2)), 4) == 0.1111

我相信你可以做到这一点的一种方法(虽然我不确定它是否是你所要求的最佳解决方案)是开发一个函数,在平面上创建一个矩形,并存储它的所有列表中的角点坐标。

每次你创建一个矩形(假设你从左下角创建它,随着你的移动增加它的 x 和 y 坐标),检查每个坐标是否 x 坐标在另一个矩形的 x 范围内,即x_min < x < x_max。如果是这样,请检查 y 坐标。如果坐标在另一个矩形的 x 和 y 范围内,则它是交集的一部分。

在创建所有坐标时重复这些操作并保存交点坐标,然后找到交点的角点。这样,您就可以计算出两个三角形之间的交集和并集面积,以及它们之间的比率。