当前位置: 首页 > news >正文

python --计算直线和矩形(矩形和矩形是否相交 嵌套 重叠)

直线和矩形是否相交(方法一)

class Intersection(object):
    '''计算直线和矩形是否相交'''
    @classmethod
    def cross_product(cls, x1, y1, x2, y2, x3, y3):
        return (x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1)

    @classmethod
    def is_intersecting(cls, x1, y1, x2, y2, x3, y3, x4, y4):
        # 计算叉积
        d1 = cls.cross_product(x1, y1, x2, y2, x3, y3)
        d2 = cls.cross_product(x1, y1, x2, y2, x4, y4)
        d3 = cls.cross_product(x3, y3, x4, y4, x1, y1)
        d4 = cls.cross_product(x3, y3, x4, y4, x2, y2)

        # 检查线段是否相交
        if ((d1 * d2 < 0) and (d3 * d4 < 0)):
            return True
        # 处理边界情况:共线且有重叠部分
        if (d1 == 0 and min(x1, x2) <= x3 <= max(x1, x2) and min(y1, y2) <= y3 <= max(y1, y2)) or \
                (d2 == 0 and min(x1, x2) <= x4 <= max(x1, x2) and min(y1, y2) <= y4 <= max(y1, y2)) or \
                (d3 == 0 and min(x3, x4) <= x1 <= max(x3, x4) and min(y3, y4) <= y1 <= max(y3, y4)) or \
                (d4 == 0 and min(x3, x4) <= x2 <= max(x3, x4) and min(y3, y4) <= y2 <= max(y3, y4)):
            return True
        return False

    @classmethod
    def line_intersects_rectangle(cls, x1, y1, x2, y2, pxmin, pymin, pxmax, pymax):
        # 矩形的四条边
        edges = [
            (pxmin, pymin, pxmin, pymax),  # left
            (pxmax, pymin, pxmax, pymax),  # right
            (pxmin, pymin, pxmax, pymin),  # top
            (pxmin, pymax, pxmax, pymax)  # bottom
        ]

        # 判断线段是否与矩形的任意一条边相交
        for edge in edges:
            if cls.is_intersecting(x1, y1, x2, y2, *edge):
                return True
        return False

    @classmethod
    def is_line_intersect_rect(cls, line, rect):
        '''计算直线和矩形是否相交'''
        x1, y1, x2, y2 = line
        pxmin, pymin, pxmax, pymax = rect
        return cls.line_intersects_rectangle(x1, y1, x2, y2, pxmin, pymin, pxmax, pymax)


# 示例使用
line = [500, 0, 500, 500]
rect = [271, 191, 672, 720]
result = Intersection.is_line_intersect_rect(line, rect)
print(f"直线与矩形是否相交: {result}")

直线和矩形是否相交(方法二)

def is_line_intersect_rect(line, rect):
    # 提取直线和矩形的坐标
    x1, y1, x2, y2 = line
    x3, y3, x4, y4 = rect

    # 快速排斥试验
    if (max(x1, x2) < min(x3, x4)) or (max(x3, x4) < min(x1, x2)) or \
            (max(y1, y2) < min(y3, y4)) or (max(y3, y4) < min(y1, y2)):
        return False

    def cross_product(x1, y1, x2, y2, x3, y3):
        return (x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1)

    # 计算矩形四个顶点相对于直线的叉积
    d1 = cross_product(x1, y1, x2, y2, x3, y3)
    d2 = cross_product(x1, y1, x2, y2, x4, y3)
    d3 = cross_product(x1, y1, x2, y2, x4, y4)
    d4 = cross_product(x1, y1, x2, y2, x3, y4)

    # 判断直线是否跨立矩形
    line_cross_rect = ((d1 < 0 and d3 > 0) or (d1 > 0 and d3 < 0)) or ((d2 < 0 and d4 > 0) or (d2 > 0 and d4 < 0))
    rect_vertices_on_line = (d1 == 0 and (x3 >= min(x1, x2) and x3 <= max(x1, x2) and y3 >= min(y1, y2) and y3 <= max(y1, y2))) or \
                            (d2 == 0 and (x4 >= min(x1, x2) and x4 <= max(x1, x2) and y3 >= min(y1, y2) and y3 <= max(y1, y2))) or \
                            (d3 == 0 and (x4 >= min(x1, x2) and x4 <= max(x1, x2) and y4 >= min(y1, y2) and y4 <= max(y1, y2))) or \
                            (d4 == 0 and (x3 >= min(x1, x2) and x3 <= max(x1, x2) and y4 >= min(y1, y2) and y4 <= max(y1, y2)))

    return line_cross_rect or rect_vertices_on_line


# 给定的直线和矩形坐标
line = [500, 0, 500, 500]
rect = [1193, 167, 1280, 716]  # 按yolo给的 左上x 左上y 右下x 右下y

result = is_line_intersect_rect(line, rect)
print(f"直线与矩形是否相交: {result}")

判断一个矩形是否在另一个矩形内

def is_rect_inside(rect1, rect2):
    """
    判断 rect1 是否在 rect2 内
    :param rect1: 第一个矩形,格式为 [x1, y1, x2, y2],(x1, y1) 是左上角坐标,(x2, y2) 是右下角坐标
    :param rect2: 第二个矩形,格式为 [x3, y3, x4, y4],(x3, y3) 是左上角坐标,(x4, y4) 是右下角坐标
    :return: 如果 rect1 在 rect2 内返回 True,否则返回 False
    """
    x1, y1, x2, y2 = rect1
    x3, y3, x4, y4 = rect2

    return x1 >= x3 and y1 >= y3 and x2 <= x4 and y2 <= y4


# 示例 1:部分重叠且满足内部条件
rect1 = [20, 20, 40, 40]
rect2 = [10, 10, 50, 50]
result1 = is_rect_inside(rect1, rect2)
print(f"rect1 是否在 rect2 内(示例 1): {result1}")

# 示例 2:部分重叠但不满足内部条件
rect3 = [30, 30, 60, 60]
rect4 = [10, 10, 50, 50]
result2 = is_rect_inside(rect3, rect4)
print(f"rect3 是否在 rect4 内(示例 2): {result2}")

# 示例 3:完全重叠
rect5 = [10, 10, 50, 50]
rect6 = [10, 10, 50, 50]
result3 = is_rect_inside(rect5, rect6)
print(f"rect5 是否在 rect6 内(示例 3): {result3}")

计算矩形和矩形相交(不含嵌套)

def is_rectangles_intersect(rect1, rect2):
    """
    判断两个矩形是否相交且不嵌套
    :param rect1: 第一个矩形,格式为 [x1, y1, x2, y2],(x1, y1) 是左上角坐标,(x2, y2) 是右下角坐标
    :param rect2: 第二个矩形,格式为 [x3, y3, x4, y4],(x3, y3) 是左上角坐标,(x4, y4) 是右下角坐标
    :return: 如果相交且不嵌套返回 True,否则返回 False
    """
    x1, y1, x2, y2 = rect1
    x3, y3, x4, y4 = rect2

    # 快速排斥试验:检查在 x 轴和 y 轴上是否无重叠
    if (x2 < x3) or (x4 < x1) or (y2 < y3) or (y4 < y1):
        return False

    # 检查是否存在嵌套情况
    is_rect1_inside_rect2 = x1 >= x3 and y1 >= y3 and x2 <= x4 and y2 <= y4
    is_rect2_inside_rect1 = x3 >= x1 and y3 >= y1 and x4 <= x2 and y4 <= y2

    if is_rect1_inside_rect2 or is_rect2_inside_rect1:
        return False

    return True

# 示例使用
rect1 = [10, 10, 50, 50]
rect2 = [30, 30, 70, 70]
result = is_rectangles_intersect(rect1, rect2)
print(f"两个矩形是否相交且不嵌套: {result}")

相关文章:

  • GitPython库快速应用入门
  • 大型语言模型Claude的“思维模式”最近被公开解剖
  • Dubbo(28)如何配置Dubbo的多注册中心支持?
  • WEB安全-CTF中的PHP反序列化漏洞
  • 【电商接口】拼多多API如何授权?
  • 监督学习凑字
  • linux线程运行记录C++
  • 11乱码问题的解释(2)
  • 同时使用Telnet和SSH登录思科交换机
  • MySQL索引与视图综合应用示例解析
  • 【Python趣味】:爬取音乐
  • C# Winform 入门(2)之发送邮件
  • MyBatis基础五(动态SQL,缓存)
  • NFS 重传次数速率监控
  • xml中配置AOP织入
  • vxe-table 树表格启用树节点连接线的使用
  • 前端简单入门学习1——使用工具
  • 企业级NoSql数据库Redis集群
  • SQL Server 八大排序算法详解
  • 【Linux网络与网络编程】03.UDP Socket编程
  • wordpress 添加分页/网站优化的方法有哪些
  • 网站开发中如何制作登录页面/黄金网站app大全
  • 紫搜做网站/营销策划的六个步骤
  • 精美企业网站/重庆百度seo整站优化