3d空间中点到线的最短距离

hel*_*lel 2 python 3d numpy vector distance

我正在尝试使用 numpy 或 python 中的任何东西找到从点 (x0,y0,z0) 到由 (x1,y1,z1) 和 (x2,y2,z2) 连接的线的最小距离。不幸的是,我在网上能找到的所有内容都与 2d 空间有关,而且我对 python 还很陌生。任何帮助将不胜感激。提前致谢!

Han*_*ave 6

StackOverflow 不支持 Latex,所以我将掩盖一些数学。一种解决方案来自这样一种想法,即如果您的线跨越点pq,则该线上的每个点都可以表示t*(p-q)+q为某个实值的t。然后,您希望最小化给定点r与该线上任何点之间的距离,距离很方便是单个变量的函数t,因此标准微积分技巧可以正常工作。考虑下面的例子,其计算之间的最小距离r和行跨区pq。用手,我们知道答案应该是1

import numpy as np

p = np.array([0, 0, 0])
q = np.array([0, 0, 1])
r = np.array([0, 1, 1])

def t(p, q, r):
    x = p-q
    return np.dot(r-q, x)/np.dot(x, x)

def d(p, q, r):
    return np.linalg.norm(t(p, q, r)*(p-q)+q-r)

print(d(p, q, r))
# Prints 1.0
Run Code Online (Sandbox Code Playgroud)

这适用于任意数量的维度,包括 2、3 和 10 亿。唯一真正的限制是pq必须是不同的点,以便它们之间有一条独特的线。

我分解了上面例子中的代码,以展示我从数学上思考它的方式(找到t然后计算距离)所产生的两个不同的步骤。这不一定是最有效的方法,如果您想知道各种点和同一条线的最小距离,则肯定不是最有效的方法——如果维数很小,则加倍如此。要获得更有效的方法,请考虑以下事项:

import numpy as np

p = np.array([0, 0, 0])  # p and q can have shape (n,) for any
q = np.array([0, 0, 1])  # n>0, and rs can have shape (m,n)
rs = np.array([          # for any m,n>0.
    [0, 1, 1],
    [1, 0, 1],
    [1, 1, 1],
    [0, 2, 1],
])

def d(p, q, rs):
    x = p-q
    return np.linalg.norm(
        np.outer(np.dot(rs-q, x)/np.dot(x, x), x)+q-rs,
        axis=1)

print(d(p, q, rs))
# Prints array([1.        , 1.        , 1.41421356, 2.        ])
Run Code Online (Sandbox Code Playgroud)

可能有一些我遗漏的简化或其他可以加快速度的事情,但这至少应该是一个好的开始。