寻找两个向量方程的交点

1 投票
3 回答
2909 浏览
提问于 2025-04-16 00:07

我一直在尝试解决这个问题,发现了一个可以计算零除错的公式。不过,这个公式并不是最好的选择:

v1 = (a,b)
v2 = (c,d)
d1 = (e,f)
d2 = (h,i)

l1: v1 + λd1
l2: v2 + µd2

Equation to find vector intersection of l1 and l2 programatically by re-arranging for lambda.

(a,b) + λ(e,f) = (c,d) + µ(h,i)
a + λe = c + µh
b +λf = d + µi
µh = a + λe - c
µi = b +λf - d
µ = (a + λe - c)/h
µ = (b +λf - d)/i
(a + λe - c)/h = (b +λf - d)/i
a/h + λe/h - c/h = b/i +λf/i - d/i
λe/h - λf/i =  (b/i - d/i) - (a/h - c/h)
λ(e/h - f/i) = (b - d)/i - (a - c)/h
λ = ((b - d)/i - (a - c)/h)/(e/h - f/i)

Intersection vector = (a + λe,b + λf)

我不确定在某些情况下它是否有效。我还没有进行测试。

我需要知道如何处理像那个例子中的a-i这样的数值。

谢谢。

3 个回答

0

在进行计算之前,确保 d1 向量和 d2 向量不是平行的(或者说几乎平行)。如果它们是平行的,那你的两条线就不会相交,这样就会出现除以零的错误。

根据你的变量,如果 (ei - fh) 的值等于或接近 0,那说明你的两条线是平行的。

1

如果你在谷歌上搜索“直线的交点”,你会发现很多公式都没有涉及到用某个坐标去除以1。维基百科上提到的sputsoft算法有个不错的解释。

关于你的数学运算,你在除以hi的时候太着急了。其实可以先不进行除法,先找到解决方案。比如,你可以把µh的方程乘以i,把µi的方程乘以h,这样就能得到两个关于µhi的方程。这样最后得到的λ方程就和你的等价,但没有可能出错的除法:

λ = ((b - d)h - (a - c)i)/(ei - fh)

只需要把你λ的上下都乘以hi就可以了。

0

这里有一个用Python写的解决方案。v1和v2是位置向量,d1和d2是方向向量。

def vector_intersection(v1,v2,d1,d2):
    '''
    v1 and v2 - Vector points
    d1 and d2 - Direction vectors
    returns the intersection point for the two vector line equations.
    '''
    if d1[0] == 0 and d2[0] != 0 or d1[1] == 0 and d2[1] != 0:
        if d1[0] == 0 and d2[0] != 0:
            mu = float(v1[0] - v2[0])/d2[0]
        elif d1[1] == 0 and d2[1] != 0:
            mu = float(v1[1] - v2[1])/d2[1]
        return (v2[0] + mu* d2[0],v2[1] + mu * d2[1])
    else:
        if d1[0] != 0 and d1[1] != 0 and d2[0] != 0 and d2[1] != 0:
            if d1[1]*d2[0] - d1[0]*d2[1] == 0:
                raise ValueError('Direction vectors are invalid. (Parallel)')
            lmbda = float(v1[0]*d2[1] - v1[1]*d2[0] - v2[0]*d2[1] + v2[1]*d2[0])/(d1[1]*d2[0] - d1[0]*d2[1])
        elif d2[0] == 0 and d1[0] != 0:
            lmbda = float(v2[0] - v1[0])/d1[0]
        elif d2[1] == 0 and d1[1] != 0:
            lmbda = float(v2[1] - v1[1])/d1[1]
        else:
            raise ValueError('Direction vectors are invalid.')
        return (v1[0] + lmbda* d1[0],v1[1] + lmbda * d1[1])

撰写回答