You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Python的两点视距验证:判断矩形障碍物是否遮挡视线

Python 两点视距遮挡判断(矩形障碍物)

核心思路

要验证两点间视距是否被矩形遮挡,本质是判断两点连线(线段)是否与矩形存在交集,包括两种核心情况:

  1. 任一站点位于矩形内部(直接被障碍物包裹)
  2. 站点连线与矩形的四条边中任意一条相交(连线穿过障碍物)

代码实现

辅助工具函数

def point_in_rect(point, x_min, x_max, y_min, y_max):
    """判断点是否在矩形范围内(含边界)"""
    x, y = point
    return x_min <= x <= x_max and y_min <= y <= y_max

def ccw(A, B, C):
    """计算三点叉积,判断转向:正=逆时针,负=顺时针,0=共线"""
    return (B[0] - A[0]) * (C[1] - A[1]) - (B[1] - A[1]) * (C[0] - A[0])

def segments_intersect(A, B, C, D):
    """判断两条线段AB和CD是否相交(含端点重合、共线重叠情况)"""
    ccw1 = ccw(A, B, C)
    ccw2 = ccw(A, B, D)
    ccw3 = ccw(C, D, A)
    ccw4 = ccw(C, D, B)

    # 跨立相交(两条线段互相穿过对方)
    if (ccw1 * ccw2 < 0) and (ccw3 * ccw4 < 0):
        return True
    
    # 端点落在另一条线段上的情况
    if ccw1 == 0 and point_in_rect(C, min(A[0], B[0]), max(A[0], B[0]), min(A[1], B[1]), max(A[1], B[1])):
        return True
    if ccw2 == 0 and point_in_rect(D, min(A[0], B[0]), max(A[0], B[0]), min(A[1], B[1]), max(A[1], B[1])):
        return True
    if ccw3 == 0 and point_in_rect(A, min(C[0], D[0]), max(C[0], D[0]), min(C[1], D[1]), max(C[1], D[1])):
        return True
    if ccw4 == 0 and point_in_rect(B, min(C[0], D[0]), max(C[0], D[0]), min(C[1], D[1]), max(C[1], D[1])):
        return True
    
    return False

视距遮挡判断主函数

def is_line_of_sight_blocked(sta1, sta2, x_min, x_max, y_min, y_max):
    """判断两点间视距是否被矩形障碍物遮挡"""
    # 获取站点坐标(适配题目中sta1.position的调用方式)
    p1 = sta1.position
    p2 = sta2.position

    # 情况1:任一站点在矩形内部,直接判定遮挡
    if point_in_rect(p1, x_min, x_max, y_min, y_max) or point_in_rect(p2, x_min, x_max, y_min, y_max):
        return True

    # 定义矩形的四条边线段
    rect_edges = [
        ((x_min, y_min), (x_max, y_min)),  # 底边
        ((x_max, y_min), (x_max, y_max)),  # 右边
        ((x_max, y_max), (x_min, y_max)),  # 顶边
        ((x_min, y_max), (x_min, y_min))   # 左边
    ]

    # 情况2:检查连线是否与矩形任意一条边相交
    for edge in rect_edges:
        if segments_intersect(p1, p2, edge[0], edge[1]):
            return True

    # 两种情况都不满足,视距畅通
    return False

测试示例

# 模拟站点类(匹配题目中sta1.position的调用逻辑)
class Station:
    def __init__(self, x, y):
        self._position = (x, y)
    
    @property
    def position(self):
        return self._position

# 实例化题目给定的站点和矩形参数
sta1 = Station(1, 5)
sta2 = Station(5, 1)
x_min, x_max = 3, 4
y_min, y_max = 2, 3

# 执行判断并输出结果
blocked = is_line_of_sight_blocked(sta1, sta2, x_min, x_max, y_min, y_max)
print(f"视距是否被遮挡: {blocked}")  # 输出:True(连线穿过矩形的(3,3)和(4,2)顶点)

关键说明

  • 叉积计算(ccw函数)是线段相交检测的核心,能高效判断点的相对位置关系
  • 函数覆盖了所有边界情况:端点重合、线段共线重叠、站点在障碍物内部等
  • 完全适配题目中给定的sta1.position调用方式,无需修改现有站点类结构

内容的提问来源于stack exchange,提问作者searcher__dm01

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 22:01:09