计算至少三个矩形之一所覆盖的面积

问题描述

我有一个问题,需要计算三个矩形中至少一个矩形所覆盖的面积。

我已经定义了一个函数calculate如下(为清楚起见,对冗余变量表示歉意):

def calculate(rec1,rec2,rec3):
    if rec1 == rec2 == rec3:
        return abs((rec1[1]-rec1[3])) * abs(rec1[0]-rec1[2])
    else:        
        area1 = abs((rec1[1]-rec1[3])) * abs(rec1[0]-rec1[2])
        area2 = abs((rec2[1]-rec2[3])) * abs(rec2[0]-rec2[2])
        area3 = abs((rec3[1]-rec3[3])) * abs(rec3[0]-rec3[2])
 
        xmin1,ymin1,xmax1,ymax1 = rec1[0],rec1[3],rec1[2],rec1[1]
        xmin2,ymin2,xmax2,ymax2 = rec2[0],rec2[3],rec2[2],rec2[1]
        xmin3,ymin3,xmax3,ymax3 = rec3[0],rec3[3],rec3[2],rec3[1]
 
        area12 = (min(xmax1,xmax2) - max(xmin1,xmin2)) * (min(ymax1,ymax2) - max(ymin1,ymin2))
        area13 = (min(xmax1,xmax3) - max(xmin1,xmin3)) * (min(ymax1,ymax3) - max(ymin1,ymin3))
        area23 = (min(xmax2,xmax3) - max(xmin2,xmin3)) * (min(ymax2,ymax3) - max(ymin2,ymin3))
        
        return (area1 + area2 + area3) - (area12 + area13 + area23)

但是,这似乎不起作用。公式中我缺少什么? area12area13area23是相交三角形的区域,该区域由末尾的最后两位数字表示,例如area12rec1的相交区域和rec2

对于输入((x1,y1)表示左上角而(x2,y2)表示右下角)

(2,-1,3,-3),(0,2,0),(-3,1,-1)

我应该得到12输出,但是我得到13并简单地将+1添加到返回值在其他测试用例中不起作用。

解决方法

您要查找的是矩形联合的面积。

对于两个矩形,该面积是各个面积的总和减去相交的面积。有趣的是,相交也是矩形(或空的)。如果用&表示交点,而用|表示并集,则有

Area(A | B) = Area(A) + Area(B) - Area(A & B).

要归纳为三个矩形,我们可以想象上述联合由两个正矩形和一个负矩形组成。因此

Area(A | B | C) = Area((A | B) | C)
 = Area(A) + Area(C) - Area(A & C) + Area(B) + Area(C) - Area(B & C) - Area(A & B) - Area(C) + Area(A & B & C)
 = Area(A) + Area(B) + Area(C) - Area(B & C) - Area(C & A) - Area(A & B) + Area(A & B & C).

然后找到两个矩形相交的区域,只需考虑两个左侧最右边和两个右侧最左边即可。如果它们相交,则交集为空。否则,它们的距离就是相交的宽度。类似的推理可以使您身高升高。