3d空间中点到线的最短距离 [英] Shortest distance between a point and a line in 3 d space
问题描述
我正在尝试使用 numpy 或 python 中的任何东西找到从点 (x0,y0,z0) 到由 (x1,y1,z1) 和 (x2,y2,z2) 连接的线的最小距离.不幸的是,我在网上能找到的所有内容都与 2d 空间有关,而且我对 python 还很陌生.任何帮助将不胜感激.提前致谢!
I am trying to find the minimum distance from a point (x0,y0,z0) to a line joined by (x1,y1,z1) and (x2,y2,z2) using numpy or anything in python. Unfortunately, all i can find on the net is related to 2d spaces and i am fairly new to python. Any help will be appreciated. Thanks in advance!
推荐答案
StackOverflow 不支持 Latex,所以我将掩盖一些数学问题.一种解决方案来自这样一种想法:如果您的线跨越点 p
和 q
,那么该线上的每个点都可以表示为 t*(pq)+q
用于一些实值 t
.然后,您希望最小化给定点 r
与该线上任何点之间的距离,距离很方便是单个变量 t
的函数,因此标准微积分技巧有效美好的.考虑以下示例,该示例计算 r
与 p
和 q
跨越的线之间的最小距离.手工,我们知道答案应该是1
.
StackOverflow doesn't support Latex, so I'm going to gloss over some of the math. One solution comes from the idea that if your line spans the points p
and q
, then every point on that line can be represented as t*(p-q)+q
for some real-valued t
. You then want to minimize the distance between your given point r
and any point on that line, and distance is conveniently a function of the single variable t
, so standard calculus tricks work fine. Consider the following example, which calculates the minimum distance between r
and the line spanned by p
and q
. By hand, we know the answer should be 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
和 q
必须是不同的点,以便它们之间有一条唯一的线.
This works fine in any number of dimensions, including 2, 3, and a billion. The only real constraint is that p
and q
have to be distinct points so that there is a unique line between them.
我在上面的例子中分解了代码,以展示我在数学上思考它的方式(找到 t
然后计算距离)产生的两个不同的步骤.这不一定是最有效的方法,如果您想知道各种点和同一条线的最小距离,则肯定不是最有效的方法——如果维数很小,则加倍如此.如需更有效的方法,请考虑以下事项:
I broke the code down in the above example in order to show the two distinct steps arising from the way I thought about it mathematically (finding t
and then computing the distance). That isn't necessarily the most efficient approach, and it certainly isn't if you want to know the minimum distance for a wide variety of points and the same line -- doubly so if the number of dimensions is small. For a more efficient approach, consider the following:
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. ])
可能有一些我遗漏的简化或其他可以加快速度的事情,但至少应该是一个好的开始.
There may well be some simplifications I'm missing or other things that could speed that up, but it should be a good start at least.
这篇关于3d空间中点到线的最短距离的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!