numpy 在3D空间中查找从点到直线的垂直距离(矢量

0kjbasz6  于 2023-08-05  发布在  其他
关注(0)|答案(3)|浏览(139)

受答案here的启发,我想计算3D空间中从一点到一条直线的垂直距离(以矢量格式而不仅仅是幅度)。
上面提到的公式给予了大小。

import numpy as np
norm = np.linalg.norm

p1 = np.array([0,0,0])
p2 = np.array([10,0,3])

p3 = np.array([6, -3, 5])

ppDist = np.abs(norm(np.cross(p2-p1, p1-p3)))/norm(p2-p1)
print(ppDist) # 4.28888043816146

字符串
ppDist向量实际上是(0.8807339448,3,-2.935779817),因此它的norm()4.288880438
这里有一个快速的可视化-x1c 0d1x

nzrxty8p

nzrxty8p1#

找到P12上P13矢量的projection,P13与投影的矢量差将是垂直矢量。

P12 = p2-p1
P13 = p3-p1

proj_13over12 = np.dot(P13, P12)*P12/norm(P12)**2 # array([6.88073394, 0.        , 2.06422018])
perpendicular = proj_13over12 - P13

print(perpendicular) # [ 0.88073394  3.         -2.93577982]

字符串


的数据

uyto3xhc

uyto3xhc2#

python
import numpy as np

def distance_point_to_line(p1, p2, p3):
    v = p2 - p1
    w = p3 - p1
    proj_w_v = np.dot(w, v) / np.dot(v, v) * v
    u = w - proj_w_v
    d = np.linalg.norm(u)
    p = p3 - u
    return d, p

字符串

dy1byipe

dy1byipe3#

我会给予OP's solution一个稍微改变的解。这是因为在OP的解决方案中,他们称之为proj_13over12的含义缺失。我们从投影中想要的实际上是位于由p1p2定义的直线上的点,当将该点与p3连接时,该点创建了一个垂直于该向量的向量。在p1 = (0,0,0)的特殊情况下,我们得到了这个结果,但是当点移动时,值不会改变。例如,对于给定的点,垂直点位于[6.88073394, 0., 2.06422018]。但是如果我们在每个方向上将所有的点平移1,我们应该得到一个垂直的点,它被平移了相同的量,但是我们没有。

import numpy as np
from numpy.linalg import norm

p1 = np.array([0, 0, 0]) + 1
p2 = np.array([10, 0, 3]) + 1
p3 = np.array([6, -3, 5]) + 1

P12 = p2-p1
P13 = p3-p1

proj_13over12 = np.dot(P13, P12)*P12/norm(P12)**2 
print(proj_13over12) # still [6.88073394, 0., 2.06422018]

字符串
我将使用一些不同的符号,这对我来说更有意义。首先,连接p1p2vector 将被称为v1(对于向量1),连接p1p2的向量将被称为v2。投影的结果将被称为projv2_v1(这在某种程度上反映了被投影到的向量是单词“proj”的下标的常见符号)。垂直点称为pperp
我们使用方程v1 (v1 dot v2)/norm(v1)^2计算投影,也可以写成v1 (v1 dot v2)/(v1 dot v1)。(数学插曲:投影是有效的,因为v1/norm(v1)给出了v1方向上的单位向量,而(v1 dot v2)/norm(v1)给出了v2方向上的向量的大小。)现在,在计算投影之后,通过将p1加回去来找到pperp(我们通过与p1取差来创建向量,基本上将所有内容都转换到原点,因此这一步转换回空间中的实际位置)。然后通过找到连接p1pperp的向量的范数来找到距离。有了这些变化,结果都有简单的物理解释。

import numpy as np
from numpy.linalg import norm

p1 = np.array([0,0,0])
p2 = np.array([10,0,3])
p3 = np.array([6, -3, 5])

v1 = p2 - p1
v2 = p3 - p1
projv2_v1 = np.dot(v1,v2)*v1/np.dot(v1, v1)
pperp = projv2_v1 + p1
print(pperp) # [6.88073394, 0., 2.06422018]
dist = norm(pperp - p3)
print(dist)  # 4.28888043816146


的数据
现在,如果我们像以前一样平移所有的点,我们得到pperp = [7.88073394, 1., 3.06422018],这是有意义的,因为它也会平移相同的量。

相关问题