两条直线,已知每条直线上的两个不同的点 求标准方程AX+BY+C=0
    def common_style(x1,y1,x2,y2):
        return y2-y1,x1-x2,x2*y1-x1*y2
根据标准方差,求直线的截距
    def line_intercept_with_commonstyle(A,B,C):
        if A==0 and B==0:return None,None
        if A==0:return None,-C/B
        if B==0:return -C/A,None
        return -C/A,-C/B
根据直线两点求截距
    def line_intercept_with_two_point(x1,y1,x2,y2):
        A,B,C = common_style(x1,y1,x2,y2)
        return line_intercept_with_commonstyle(A,B,C)
根据线段两点 求截距
def line_seg_intercept_with_two_point(x1,y1,x2,y2):
        # 根据线段两点 求截距
        x_d,y_d = line_intercept_with_two_point(x1,y1,x2,y2)
        if x_d == None and y_d==None:
            return None,None

        # 平行x轴 且与y轴无交点
        if x_d == None and (min(x1,x2)>0 or max(x1,x2)<0):
            return None,None
        # 平行y轴 且与x轴无交点
        if y_d== None and (min(y1,y2)>0 or max(y1,y2)<0):
            return None,None

        if point_in_line_seg(x1,y1,x2,y2,x_d,0) and point_in_line_seg(x1,y1,x2,y2,0,y_d):
            return x_d,y_d

        if point_in_line_seg(x1,y1,x2,y2,x_d,0):
            return x_d,None

        return None,y_d
判断点是否在 两个点构成的线段上 即是否三点共线段
        def point_in_line_seg(x1,y1,x2,y2,x3,y3):
            if x1==x3 and y1==y3: return True
            if x2==x3 and y2==y3:return True
            if x1==x3 and y1!=y3:return False
            if x2==x3 and y2!=y3:return False

            # 斜率不一样
            if (y2-y1)/(x2-x1)!=(y3-y1)/(x3-x1):return False
            # 在线段上
            if x3<=max(x1,x2) and x3>=min(x1,x2) and y3>=min(y1,y2) and y3<=max(y1,y2):
                return True
            return False
判断两个线段是否有交点,写出交点x最小的那个坐标,如果一样,写y较小的

思路:这一问题主要是特殊情况的处理很麻烦。
0.完全重叠,直接返回坐标小的点
1.如果在x,y轴上的投影有不重叠的,那么这两个线段一定不重叠。
因为重叠部分的投影一定相同,所以必须有重叠的。
2.先考虑直线,需要判断斜率是否存在,斜率是否相同。
如果斜率都不存在,判断他们有无交点。这里由于0的筛选所以肯定有交点,直接返回满足条件的坐标即可。
其中的一个不存在,判断另一个直线和该直线构成的点,是否在两个线段上。可以用上面的函数。
3.如果斜率存在,但是相等。由于0的判断,把投影不重复的全去掉了。这样可以避免两个线段在同一个直线上但是没有交点的情况。所以如果斜率相等,判断截距是否一样即可

4.其余情况 就是普通情况可以用 公式计算。详情看代码


def intersection(self, start1, end1, start2, end2):
   
    [x0,y0],[x1,y1],[x2,y2],[x3,y3] = start1,end1,start2,end2

        d = [start1, end1, start2, end2]
        d = sorted(d)

        # 重合情况
        if x0 == x2 and y0==y2 and x1==y3 and y1==y3:
            return list(d[1])

        # x,y 以及他的投影都不重合的情况 一定不存在 交点
        if min(x1,x0)>max(x2,x3) or max(x1,x0)<min((x3,x2)):
            return []
        if min(y1,y0)>max(y2,y3) or max(y1,y0)<min((y3,y2)):
            return []

        # 判断斜率不存在在情况
        # 斜率都不存在 这个时候必须x都一样
        if x0==x1 and x2==x3:
            if x1!=x3 or min(y0,y1)>max(y2,y3) or max(y0,y1)<min(y2,y3):
                return []
            return list(d[1])

        # 第一条斜率不存在
        if x0 == x1:
            A,B,C = common_style(x2,y2,x3,y3)
            x_j,y_j = x1,x_to_y(A,B,C,x0)
            if point_in_line_seg(x0,y0,x1,y1,x_j,y_j):
                return [x_j,y_j]

        # 第2条斜率不存在
        elif x2==x3:
            A, B, C = common_style(x0, y0, x1, y1)
            x_j, y_j = x2, x_to_y(A, B, C, x0)
            if point_in_line_seg(x2, y2, x3, y3, x_j, y_j):
                return [x_j, y_j]

        # 斜率相等
        if (y1-y0)/(x1-x0)==(y3-y2)/(x3-x2):
            if line_seg_intercept_with_two_point(x0,y0,x1,y1)[1]==line_seg_intercept_with_two_point(x2,y2,x3,y3)[1]:
                return list(d[1])
            return []

        y = ((y0-y1)*(y3-y2)*x0 + (y3-y2)*(x1-x0)*y0 + (y1-y0)*(y3-y2)*x2 + (x2-x3)*(y1-y0)*y2 ) / ( (x1-x0)*(y3-y2) + (y0-y1)*(x3-x2) )
        x = x2 + (x3-x2)*(y-y2) / (y3-y2)
        if point_in_line_seg(x0,y0,x1,y1,x,y) and point_in_line_seg(x2,y2,x3,y3,x,y):return [x,y]

        return []

北语张益达
6 声望4 粉丝