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

3

我有一条线段和一个点,希望能找到这条直线上的一个点 (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
1个回答

11

这将需要一些数学来从解析上确定。通过“90度”,我假设您想找到在此3D直线上的点,如果您从此交点向所需点延伸一条线,该点将与此直线垂直

我假设两个点ab表示它们在3D空间中可以连接它们的线的坐标,而c是感兴趣的点。这里是一个更好的图表说明我所说的:

来源:MathWorld

在您的情况下,x1x2 分别代表您代码中的 ab,而 x0 代表 c。如果您从交点处向点 c 延伸一条线,距离 d 将是使该点垂直于该线的线上的距离。

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

这条线上介于 x1x2 之间的一个点可以用上述参数形式中每个 (x,y,z) 值来描述,并变化参数 t,该参数从 [0,1] 取值。 因此,t=0 给出第一个点 x1at=1 给出第二个点 x2b。 在 [0,1] 之间的任何 t 值都会给您沿着该线的一点。 目标是找到使得距离点 x0c 最小的值 t。 正如我之前所说,我们都知道几何学中,从交点向点 x0c 延伸一条线,最小距离将使交角垂直 / 90 度。
因此,你所要做的就是找到这个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;

我用矩阵乘法实现了代码中的 t。点积可以通过将行向量乘以列向量来计算,如果这两个向量的系数相同,则结果是一个向量的模长的平方。
对于你的示例,我们得到:
Xinter =

   16.9889   23.7211   76.0539

为了证明这是正确的,让我们绘制该直线、点和交点:

enter image description here

生成上述图形的代码是:
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;

1
好的。单凭解释的努力就值得点赞。 - Hoki

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接