我在确定此 python 代码中两条线的交点时遇到问题

I'm having a problem with determining the intersection of two lines in this python code

我尝试了解析几何的数学公式,但没有得到想要的结果。

正如您在代码中看到的那样,用户画了两条线并出现了一个绿色圆圈(交点)。

我已经尝试解决这个问题几个小时了,但我失败了。有时点不出现或出现但在错误的位置。

Source of the formula I used in the code

Docs of pygame the library I used

#!/usr/bin/env python
from pygame import *
from time import sleep
init();
win = display.set_mode((500,500));
lines = []
cords = []
preview = False
xi = -100
yi = -100
def drawlines(flines):
    for fcords in flines:
        draw.line(win,(0,0,0),fcords[0],fcords[1],4)
while True:
    win.fill((255,255,255))
    for ev in event.get():
        if ev.type == QUIT:
            quit();
            exit();
        elif ev.type == MOUSEBUTTONDOWN:
            if ev.button == 1:
                preview = True
                a = mouse.get_pos()
                cords.append(mouse.get_pos())
        elif ev.type == MOUSEBUTTONUP:
            if ev.button == 1:
                cords.append(mouse.get_pos())
                lines.append((cords))
                cords = []
                preview = False
######################################## THIS BROKEN PART #################################
    if len(lines) == 2:
        #line 1
        points_line1 = lines[0]

        point1_line1 = points_line1[0]
        point2_line1 = points_line1[1]

        line1_vector = (point2_line1[0]-point1_line1[0],point2_line1[1]-point1_line1[1])
        a_line1 = line1_vector[1]
        b_line1 = -line1_vector[0]
        
        c_line1 = -((a_line1*point1_line1[0]) + (b_line1*point1_line1[1]))
        #line2
        points_line2 = lines[1]

        point1_line2 = points_line2[0]
        point2_line2 = points_line2[1]

        line2_vector = (point2_line2[0]-point1_line2[0],point2_line2[1]-point1_line2[1])
        
        a_line2 = line2_vector[1]
        b_line2 = -line2_vector[0]
        c_line2 = -((a_line2*point1_line2[0]) + (b_line2*point1_line2[1]))
        if (a_line2 != 0 and b_line2 != 0):
            if (a_line1 / a_line2) != ( b_line1/b_line2):
                #intersection between line1 and line2
                yi = ((((a_line1*c_line2) / a_line2) + c_line1) / -b_line1)
                xi = (((-b_line1*yi)-c_line1) / a_line1)
###########################################################################################
    elif preview:
        draw.line(win,(0,0,0),a,mouse.get_pos(),4)
    drawlines(lines)
    draw.circle(win,(0,200,0),(int(xi),int(yi)),10)
    display.flip()

很难挖掘您的代码。特别是 c_line1 = -((a_line1*point1_line1[0]) + (b_line1*point1_line1[1])) 看起来很奇怪,因为它计算的是向量和一个点的点积。
因此我不知道你的代码到底出了什么问题,但我知道如何交叉线。参见 and Collision and Intersection - Line and line

编写可以加、减、缩放向量和将向量旋转 90° 的函数。编写一个函数来计算 Dot product:

def add(a, b):
    return a[0]+b[0], a[1]+b[1]

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

def rot90(v):
    return -v[1], v[0]

def mul(v, s):
    return v[0]*s, v[1]*s

def dot(a, b):
    return a[0]*b[0] + a[1]*b[1]

计算从线的起点到线的终点的向量和线的法向量。将线向量旋转90°得到法向量:

#line 1
point1_line1, point2_line1 = lines[0]
line1_vector = sub(point2_line1, point1_line1)
line1_norml  = rot90(line1_vector)

#line2
point1_line2, point2_line2 = lines[1]
line2_vector = sub(point2_line2, point1_line2)
line2_norml  = rot90(line2_vector)

计算线段的交点。确保直线不平行且交点在线段上:

# vector from start point of line 2 to start point of line 1
l2p1_l1p1 = sub(point1_line1, point1_line2)

# intersection
d = dot(line2_vector, line1_norml)
if d != 0: # prallel lines
    t = dot(l2p1_l1p1, line1_norml) / d
    u = dot(l2p1_l1p1, line2_norml) / d
    if 0 <= t <= 1 and 0 <= u <= 1: # intersection on line segments
        xi, yi = add(point1_line2, mul(line2_vector, t))

最小示例:

from pygame import *
init()
win = display.set_mode((500,500))
lines = []
cords = []
preview = False
xi, yi = -100, -100

def drawlines(flines):
    for fcords in flines:
        draw.line(win,(0,0,0),fcords[0],fcords[1],4)

def add(a, b):
    return a[0]+b[0], a[1]+b[1]

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

def rot90(v):
    return -v[1], v[0]

def mul(v, s):
    return v[0]*s, v[1]*s

def dot(a, b):
    return a[0]*b[0] + a[1]*b[1]

run = True
while run:
    
    for ev in event.get():
        if ev.type == QUIT:
            run = False    
        elif ev.type == MOUSEBUTTONDOWN:
            if ev.button == 1:
                preview = True
                a = ev.pos
                cords.append(a)
        elif ev.type == MOUSEBUTTONUP:
            if ev.button == 1:
                cords.append(ev.pos)
                lines.append((cords))
                cords = []
                preview = False

    intersections = []
    for i, line1 in enumerate(lines):
        for line2 in lines[i+1:]:
            #line 1
            point1_line1, point2_line1 = line1
            line1_vector = sub(point2_line1, point1_line1)
            line1_norml  = rot90(line1_vector)
            
            #line2
            point1_line2, point2_line2 = line2
            line2_vector = sub(point2_line2, point1_line2)
            line2_norml  = rot90(line2_vector)

            # vector from start point of line 2 to start point of line 1
            l2p1_l1p1 = sub(point1_line1, point1_line2)

            # intersection
            d = dot(line2_vector, line1_norml)
            if d != 0: # prallel lines
                t = dot(l2p1_l1p1, line1_norml) / d
                u = dot(l2p1_l1p1, line2_norml) / d
                if 0 <= t <= 1 and 0 <= u <= 1: # intersection on line segments
                    xi, yi = add(point1_line2, mul(line2_vector, t))
                    intersections.append((xi, yi))

    win.fill((255,255,255))
    if len(cords) % 2 == 1:
        draw.line(win,(0,0,0), a, mouse.get_pos(), 4)
    drawlines(lines)
    for p in intersections:
        draw.circle(win, (0,200,0), (round(p[0]), round(p[1])), 10)
    display.flip()

quit()
exit()