这将需要一些数学来从解析上确定。通过“90度”,我假设您想找到在此3D直线上的点,如果您从此交点向所需点延伸一条线,该点将与此直线垂直。
我假设两个点a
和b
表示它们在3D空间中可以连接它们的线的坐标,而c
是感兴趣的点。这里是一个更好的图表说明我所说的:
![](https://istack.dev59.com/zM8tg.gif)
来源:MathWorld
在您的情况下,x1
和 x2
分别代表您代码中的 a
和 b
,而 x0
代表 c
。如果您从交点处向点 c
延伸一条线,距离 d
将是使该点垂直于该线的线上的距离。
您可以定义一个参数方程来描述 x1
和 x2
之间的直线,如下所示:
![](https://istack.dev59.com/vs7eM.gif)
这条线上介于
x1
和
x2
之间的一个点可以用上述参数形式中每个
(x,y,z)
值来描述,并变化参数
t
,该参数从
[0,1]
取值。 因此,
t=0
给出第一个点
x1
或
a
,
t=1
给出第二个点
x2
或
b
。 在
[0,1]
之间的任何
t
值都会给您沿着该线的一点。 目标是找到使得距离点
x0
或
c
最小的值
t
。 正如我之前所说,我们都知道几何学中,从交点向点
x0
或
c
延伸一条线,最小距离将使交角垂直 / 90 度。
因此,你所要做的就是找到这个
t
的值,然后将其代入上述参数方程中,以找到你想要的点。换句话说,我们希望最小化点与直线之间的距离,而该距离可以描述如下:
![](https://istack.dev59.com/uwa8u.gif)
要找到最小距离,需要通过对参数
t
求导并将导数设置为0来最小化上述方程。从逻辑上讲,您需要对方程取平方根,以使距离最小化,而不是距离的平方被最小化。但事实上,最小化距离的平方更容易,这就是为什么上述方程如此表示的原因。这是有道理的,因为如果你最小化距离的平方...距离也会被最小化,因为你只需在答案上放置一个平方根即可获得所需的结果。从方程中消除平方根可以使计算导数变得更容易。
如果您这样做,并解出
t
,我们得到以下方程式:
![](https://istack.dev59.com/h2OJa.gif)
因此,找到
a
和
c
之间的差异,将其与
b
和
a
之间的差异进行点乘积,然后将其除以
b
和
a
之间的差异的平方幅值。这解决了
t
的问题,然后你会将这个值代入上述参数方程中找到你的点。
在MATLAB代码中,它可能类似于这样:
a = [1 1 2]
b = [20 28 90]
c = [50 30 67]
ab = b - a
%// -(x1 - x0).(x2 - x1) / (|x2 - x1|^2)
t = -(a - c)*(ab.') / (ab*ab.')
%// Find point of intersection
Xinter = a + (b - a)*t
我用矩阵乘法实现了代码中的
t
。点积可以通过将行向量乘以列向量来计算,如果这两个向量的系数相同,则结果是一个向量的模长的平方。
对于你的示例,我们得到:
Xinter =
16.9889 23.7211 76.0539
为了证明这是正确的,让我们绘制该直线、点和交点:
![enter image description here](https://istack.dev59.com/jCIVB.webp)
生成上述图形的代码是:
figure;
plot3([a(1) b(1)], [a(2) b(2)], [a(3) b(3)]);
hold on;
plot3(c(1), c(2), c(3), 'r.');
plot3(Xinter(1), Xinter(2), Xinter(3), 'g.');
plot3([c(1) Xinter(1)], [c(2) Xinter(2)], [c(3) Xinter(3)], 'k');
grid;