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

如何修复Python线段相交函数在共享端点时的失效问题

问题描述

现有两条水平线段:线段1端点为(1,1)、(4,1),线段2端点为(4,1)、(8,1),二者共享端点(4,1)。

调用自定义的线段相交函数时,输出为0,因为div的值为0,函数判定两条线段为平行线并返回0。需要修改该函数,使其能识别这种共享端点的情况,并返回该公共端点作为交点。

我的Python相交函数如下:

def line_intersection (line1, line2): 
    line1 = eval(str(line1))
    line2 = eval(str(line2))
    
    x1,x2,x3,x4  = float(line1[0][0]),float(line1[1][0]),float(line2[0][0]),float(line2[1][0])
    y1,y2,y3,y4  = float(line1[0][1]),float(line1[1][1]),float(line2[0][1]),float(line2[1][1])
    


    xdiff = (x1- x2,  x3 - x4)
    ydiff = (y1 - y2, y3 - y4)

    def det(a, b):
        i = a[0] * b[1] 
        j =  a[1] * b[0]
        return i - j

    div = det(xdiff, ydiff)
    if div == 0:
        # print("lines do not intersect")
        return 0

    d = (det(*line1), det(*line2))
    x = det(d, xdiff) 
    x = x/ div
    y = det(d, ydiff) 
    y = y /div
    point = (x, y)
    

    x1, x2 = sorted([x1, x2])
    y1, y2 = sorted([y1, y2])
    if x < x1 or x > x2 or y < y1 or y > y2:
        # print("intersection point not within line segment")
        return 0

    x1, x2 = sorted([x1, x2])
    y1, y2 = sorted([y1, y2])
    if x < x1 or x > x2 or y < y1 or y > y2:
        # print("intersection point not within line segment")
        return 0

        return point

line1 = ((1, 1), (4, 1))
line2 = ((4, 1), (8, 1))
print(line_intersection(line1, line2))
解决方案

当div == 0时,两条线段要么平行要么共线。此时需要额外检查线段的端点是否重合,或线段是否存在重叠区间。以下是修改后的函数:

def line_intersection(line1, line2):
    # 直接解析线段端点,移除不安全的eval调用
    (x1, y1), (x2, y2) = line1
    (x3, y3), (x4, y4) = line2
    x1, x2, x3, x4 = float(x1), float(x2), float(x3), float(x4)
    y1, y2, y3, y4 = float(y1), float(y2), float(y3), float(y4)

    xdiff = (x1 - x2, x3 - x4)
    ydiff = (y1 - y2, y3 - y4)

    def det(a, b):
        return a[0] * b[1] - a[1] * b[0]

    div = det(xdiff, ydiff)
    if div != 0:
        # 非平行线段,计算交点
        d = (det((x1, y1), (x2, y2)), det((x3, y3), (x4, y4)))
        x = det(d, xdiff) / div
        y = det(d, ydiff) / div
        point = (x, y)

        # 检查交点是否在线段1范围内
        min_x1, max_x1 = sorted([x1, x2])
        min_y1, max_y1 = sorted([y1, y2])
        if not (min_x1 <= x <= max_x1 and min_y1 <= y <= max_y1):
            return 0

        # 检查交点是否在线段2范围内
        min_x2, max_x2 = sorted([x3, x4])
        min_y2, max_y2 = sorted([y3, y4])
        if not (min_x2 <= x <= max_x2 and min_y2 <= y <= max_y2):
            return 0

        return point
    else:
        # 平行或共线情况,检查端点是否在线段上
        def point_on_segment(px, py, seg_x1, seg_y1, seg_x2, seg_y2):
            min_x = min(seg_x1, seg_x2)
            max_x = max(seg_x1, seg_x2)
            min_y = min(seg_y1, seg_y2)
            max_y = max(seg_y1, seg_y2)
            # 先判断坐标区间,再验证共线
            return (min_x <= px <= max_x and min_y <= py <= max_y) and \
                   (det((px - seg_x1, py - seg_y1), (seg_x2 - seg_x1, seg_y2 - seg_y1)) == 0)

        intersections = []
        # 检查线段1的端点是否在seg2上
        if point_on_segment(x1, y1, x3, y3, x4, y4):
            intersections.append((x1, y1))
        if point_on_segment(x2, y2, x3, y3, x4, y4):
            intersections.append((x2, y2))
        # 检查线段2的端点是否在seg1上,避免重复添加
        if point_on_segment(x3, y3, x1, y1, x2, y2) and (x3, y3) not in intersections:
            intersections.append((x3, y3))
        if point_on_segment(x4, y4, x1, y1, x2, y2) and (x4, y4) not in intersections:
            intersections.append((x4, y4))

        # 返回第一个有效交点(如共享端点),无交点则返回0
        return intersections[0] if intersections else 0

line1 = ((1, 1), (4, 1))
line2 = ((4, 1), (8, 1))
print(line_intersection(line1, line2))  # 输出:(4.0, 1.0)

关键修改点

  • 移除了不安全的eval调用,直接解构传入的线段元组,提升代码安全性与效率。
  • 新增point_on_segment辅助函数,用于判断点是否在线段上(含端点)。
  • 在平行/共线分支中,检查所有端点是否属于另一条线段,收集并返回有效交点。
  • 修正原函数中return point的缩进错误,确保非平行情况能正确返回交点。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 08:23:55