找到垂直于目标点的3D线上的交点

Tai*_*han 2 matlab geometry linear-algebra

我有一条线和一条点,(x,y,z)如果我要从这个交点与另一个点画一条线,我想在线上找到一个90度或垂直的点.

到目前为止,我可以使用此代码创建一行,我有另一个代码来计算三点之间的角度,但这并不适用于此:

a = [1 1 2]; %line
b = [20 28 90]; % line

c = [50 30 67]; %point 

ab = b - a;


n = max(abs(ab)) + 1;

s = repmat(linspace(0, 1, n)', 1, 3);
for d = 1:3
    s(:, d) = s(:, d) * ab(d) + a(d);
end


s = round(s);


Z = 100; 
N = 100;
X = zeros(N, N, Z);

X(sub2ind(size(X), s(:, 1), s(:, 2), s(:, 3))) = 1;


x = c(:,1);


clf

plot3(s(:, 1), s(:, 2), s(:, 3), 'r.-')


axis(N * [0 1 0 1 0 1])
grid on
Run Code Online (Sandbox Code Playgroud)

ray*_*ica 8

这将需要一些数学来分析地确定.通过"90度",我假设您想要在此3D线上找到与此线垂直的点(如果您将此线从此交叉点延伸到所需点).

我假设这两个点a并且b表示3D空间中的坐标,其中一条线可以连接它们并且这c是感兴趣的点.这是我正在谈论的更好的图表:

资料来源:MathWorld

在你的情况,x1x2表示a,并b在你的代码和x0表示c.d如果您将一条线从交叉点延伸到该点,则该距离将是该线上允许该点垂直于该线的距离c.

您可以定义一个参数方程式来描述之间的线条x1,x2如下所示:

x1和之间的这一行上的一个点x2可以通过将每个(x,y,z)值取为x1x2以上述参数形式写入并改变参数t来描述[0,1].因此t=0会给你的第一个点x1at=1会给你第二个点x2b.t中间的任何值[0,1]都会给你一个点.我们的目标是找到该值t减少从远处x0c以这条线.就像我之前说过的那样,我们都知道几何学中,如果你从这个交点到一个点x0或那个点延伸一条线,那么从一个点到一条线的最小距离会使交叉角垂直/ 90度c.

因此,您所要做的就是找到此值t,然后将其替换为上述参数方程式以找到您想要的点.换句话说,我们希望最小化点和线之间的距离,并且距离可以这样描述:

要找到最小距离,您可以t通过找到相对于t它的导数并将其设置为等于0 来找到最小化上述等式的参数.从逻辑上讲,您将采用等式的平方根,以便最小化距离,而不是距离平方.然而,实际上更容易将距离平方最小化,这就是为什么上面的等式如此表示的原因.这是有道理的,因为如果你最小化距离平方......距离也会被最小化,因为你只是在答案上放置一个平方根来得到你所要求的.从等式中消除平方根将使得导数的计算更容易.

如果你这样做,并解决t,我们得到这个等式:

因此,找到之间的区别ac,借此与点积与之间的区别ba,然后通过平方之间的差异的大小划分这个ba.这解决了t,然后你将其替换为上面的参数方程来找到你的观点.

在MATLAB代码中,它看起来像这样:

a = [1 1 2]; %line - x1
b = [20 28 90]; % line - x2

c = [50 30 67]; %point - x0

ab = b - a; %// Find x2 - x1

%// -(x1 - x0).(x2 - x1) / (|x2 - x1|^2)
t = -(a - c)*(ab.') / (ab*ab.'); %// Calculate t

%// Find point of intersection
Xinter = a + (b - a)*t;
Run Code Online (Sandbox Code Playgroud)

t我的代码利用了矩阵乘法.可以通过将行数组乘以列数组并以类似的方式找到点积,如果行数组和列数组具有相同的系数,则这导致向量的幅度平方.

以您为例,我们得到:

Xinter =

   16.9889   23.7211   76.0539
Run Code Online (Sandbox Code Playgroud)

为了表明这是正确的,让我们绘制线条,点和交点:

在此输入图像描述

产生上图的代码是:

figure;

%// Plot line
plot3([a(1) b(1)], [a(2) b(2)], [a(3) b(3)]);
hold on;

%// Plot point of interest in red
plot3(c(1), c(2), c(3), 'r.');

%// Plot intersection point in green
plot3(Xinter(1), Xinter(2), Xinter(3), 'g.');

%// Plot line from intersection point to point of interest in black
plot3([c(1) Xinter(1)], [c(2) Xinter(2)],  [c(3) Xinter(3)], 'k');

%// Turn on a grid
grid;
Run Code Online (Sandbox Code Playgroud)