StackOverflow 不支持 Latex,因此我将忽略一些数学知识。一种解决方案来自这样的想法:如果你的线跨越了点p
and q
,那么该线上的每个点都可以表示为t*(p-q)+q
对于一些实值t
。然后您想要最小化给定点之间的距离r
以及该线上的任何点,距离很方便地是单个变量的函数t
,所以标准的微积分技巧效果很好。考虑以下示例,该示例计算之间的最小距离r
和跨越的线p
and q
。通过手工,我们知道答案应该是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
这在任何维度上都可以正常工作,包括 2、3 和 10 亿。唯一真正的限制是p
and q
必须是不同的点,以便它们之间有一条独特的线。
我在上面的示例中分解了代码,以便展示我从数学角度思考它的方式所产生的两个不同的步骤(发现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. ])
我可能缺少一些简化或其他可以加快速度的东西,但这至少应该是一个好的开始。