矩形

矩形

应用

应用1:Leetcode 223. 矩形面积

题目

223. 矩形面积

给你 二维 平面上两个 由直线构成且边与坐标轴平行/垂直 的矩形,请你计算并返回两个矩形覆盖的总面积。

每个矩形由其 左下 顶点和 右上 顶点坐标表示:

  • 第一个矩形由其左下顶点 (ax1, ay1) 和右上顶点 (ax2, ay2) 定义。

  • 第二个矩形由其左下顶点 (bx1, by1) 和右上顶点 (bx2, by2) 定义。

示例 1:

Rectangle Area
输入:ax1 = -3, ay1 = 0, ax2 = 3, ay2 = 4, bx1 = 0, by1 = -1, bx2 = 9, by2 = 2
输出:45

解题思路

两个矩形覆盖的总面积等于两个矩形的面积之和减去两个矩形的重叠部分的面积。

由于两个矩形的左下顶点和右上顶点已知,因此两个矩形的面积可以直接计算。如果两个矩形重叠,则两个矩形的重叠部分也是矩形,重叠部分的面积可以根据重叠部分的边界计算。

两个矩形的在坐标轴上的投影:

  • 水平边投影到 \(x\) 轴上的线段分别为 \([a_{x1},\ a_{x2}]\)\([b_{x1}, b_{x2}]\)

  • 竖直边投影到 \(y\) 轴上的线段分别为 \([a_{y1}, a_{y2}]\)\([b_{y1}, b_{y2}]\)

如果两个矩形重叠,则对于重叠部分:

  • 水平边投影到 \(x\) 轴上的线段为 \([max(a_{x1}, b_{x1}), min(a_{x2}, b_{x2})]\)

  • 竖直边投影到 \(y\) 轴上的线段为 \([max(a_{y1}, b_{y1}), min(a_{y2}, b_{y2})]\)

根据重叠部分的水平边投影到 \(x\) 轴上的线段长度和竖直边投影到 \(y\) 轴上的线段长度,即可计算重叠部分的面积。

注意:只有当两条线段的长度都大于 0 时,重叠部分的面积才大于 0,否则重叠部分的面积为 0。

代码实现

class Solution:
    def computeArea(self, ax1: int, ay1: int, ax2: int, ay2: int, bx1: int, by1: int, bx2: int, by2: int) -> int:
        # 先求重叠部分的长和宽
        x = max(0, min(ax2, bx2) - max(ax1, bx1))
        y = max(0, min(ay2, by2) - max(ay1, by1))
        # 总面积=两个矩形的面积 - 重合部分的面积
        return (ax2 - ax1) * (ay2 - ay1) + (bx2 - bx1) * (by2 - by1) - x * y

应用场景

应用场景:目标检测计算 IOU(Intersection over Union)。

应用2:Leetcode 391. 完美矩形

题目

391. 完美矩形

给你一个数组 rectangles ,其中 rectangles[i] = [xi, yi, ai, bi] 表示一个坐标轴平行的矩形。这个矩形的左下顶点是 (xi, yi) ,右上顶点是 (ai, bi) 。

如果所有矩形一起精确覆盖了某个矩形区域,则返回 true ;否则,返回 false 。

示例 1:

image
输入:rectangles = [[1,1,3,3],[3,1,4,2],[3,2,4,4],[1,3,2,4],[2,3,3,4]]
输出:true
解释:5 个矩形一起可以精确地覆盖一个矩形区域。

解题思路

如果是完美矩形,那么除了完美矩形四周的顶点只出现一次以外,其他子矩形所有的顶点重合次数只能为2或者4,并且所有子矩形的面积和要和最后组成的大矩形面积相等。

代码实现

class Solution:
    def isRectangleCover(self, rectangles: List[List[int]]) -> bool:
        seen = set()
        # 累加所有矩形的面积
        areas = 0
        for i, rect in enumerate(rectangles):
            p1, p2, p3, p4 = (rect[0], rect[1]), (rect[2], rect[1]), (rect[2], rect[3]), (rect[0], rect[3])
            points = [p1, p2, p3, p4]
            for point in points:
                if point in seen:
                    seen.remove(point)
                else:
                    seen.add(point)

            areas += (rect[2] - rect[0]) * (rect[3] - rect[1])

        if len(seen) != 4:
            return False

        seen = sorted(seen, key=lambda x: (x[0], x[1]))
        # 求大矩形的面积
        s = (seen[3][0] - seen[0][0]) * (seen[3][1] - seen[0][1])
        return areas == s
posted @ 2023-09-05 20:35  LARRY1024  阅读(34)  评论(0编辑  收藏  举报