在垂直于目标点的 3D 线上找到交点
Finding the point of intersection on a 3D line perpendicular to a target point
我有一条线和一个点,如果我要从该点与另一点的交点画一条线,我想在该线上找到一个 90 度或垂直的点 (x,y,z)
。
到目前为止,我可以用这段代码创建一条线,我还有另一个代码可以计算三点之间的角度,但这在这里并不适用:
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
这需要一些数学知识来分析确定。通过“90 度”,我假设您想在这条 3D 线上找到与这条线 垂直 的点,如果您从这个交点延伸一条线到所需的观点。
我假设 a
和 b
这两个点表示 3D space 中的坐标,其中一条线可以连接它们并且 c
是点兴趣。这是我正在谈论的更好的图表:
来源:MathWorld
在您的例子中,x1
和 x2
在您的代码中表示 a
和 b
,x0
表示 c
。如果从交点延伸一条线到点 c
,距离 d
将是允许该点垂直于这条线的直线距离。
您可以定义一个参数方程来描述 x1
和 x2
之间的直线,如下所示:
x1
和 x2
之间这条直线上的一个点可以通过取 x1
和 x2
的每个 (x,y,z)
值并写入来描述它采用上述参数形式并改变参数 t
,它来自 [0,1]
。因此 t=0
会给你第一点 x1
或 a
而 t=1
会给你第二点 x2
或 b
。 [0,1]
之间的任何 t
值都会给你一个沿线的点。 objective 是找到 t
的值 最小化 从 x0
或 c
到这条线的距离。就像我之前说的,我们都从几何学中知道,如果从这个交点延伸一条线到 x0
点或 c
.
因此,你所要做的就是找到t
的这个值,然后将其代入上面的参数方程,找到你想要的点。换句话说,我们想要最小化点和线之间的距离,距离可以这样描述:
要找到最小距离,您可以通过找到关于 t
的导数并将其设置为 0 来找到使上述方程最小化的参数 t
。从逻辑上讲,您会取方程的平方根,这样你就可以最小化距离,而不是距离的平方。然而,最小化距离的平方实际上更容易,这就是为什么上面的等式是这样表示的。这是有道理的,因为如果你最小化距离的平方……距离也会最小化,因为你只需在答案上放一个平方根就可以得到你所要求的。从等式中消除平方根将使计算导数更容易。
如果你这样做,并求解 t
,我们得到这个等式:
因此,找出 a
和 c
之间的差异,将其与 b
和 a
之间的差异进行点积,然后将其除以b
和 a
之间差值的平方。这解决了 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
为了证明这是正确的,让我们画出直线、点和交点:
生成上图的代码是:
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;
我有一条线和一个点,如果我要从该点与另一点的交点画一条线,我想在该线上找到一个 90 度或垂直的点 (x,y,z)
。
到目前为止,我可以用这段代码创建一条线,我还有另一个代码可以计算三点之间的角度,但这在这里并不适用:
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
这需要一些数学知识来分析确定。通过“90 度”,我假设您想在这条 3D 线上找到与这条线 垂直 的点,如果您从这个交点延伸一条线到所需的观点。
我假设 a
和 b
这两个点表示 3D space 中的坐标,其中一条线可以连接它们并且 c
是点兴趣。这是我正在谈论的更好的图表:
来源:MathWorld
在您的例子中,x1
和 x2
在您的代码中表示 a
和 b
,x0
表示 c
。如果从交点延伸一条线到点 c
,距离 d
将是允许该点垂直于这条线的直线距离。
您可以定义一个参数方程来描述 x1
和 x2
之间的直线,如下所示:
x1
和 x2
之间这条直线上的一个点可以通过取 x1
和 x2
的每个 (x,y,z)
值并写入来描述它采用上述参数形式并改变参数 t
,它来自 [0,1]
。因此 t=0
会给你第一点 x1
或 a
而 t=1
会给你第二点 x2
或 b
。 [0,1]
之间的任何 t
值都会给你一个沿线的点。 objective 是找到 t
的值 最小化 从 x0
或 c
到这条线的距离。就像我之前说的,我们都从几何学中知道,如果从这个交点延伸一条线到 x0
点或 c
.
因此,你所要做的就是找到t
的这个值,然后将其代入上面的参数方程,找到你想要的点。换句话说,我们想要最小化点和线之间的距离,距离可以这样描述:
要找到最小距离,您可以通过找到关于 t
的导数并将其设置为 0 来找到使上述方程最小化的参数 t
。从逻辑上讲,您会取方程的平方根,这样你就可以最小化距离,而不是距离的平方。然而,最小化距离的平方实际上更容易,这就是为什么上面的等式是这样表示的。这是有道理的,因为如果你最小化距离的平方……距离也会最小化,因为你只需在答案上放一个平方根就可以得到你所要求的。从等式中消除平方根将使计算导数更容易。
如果你这样做,并求解 t
,我们得到这个等式:
因此,找出 a
和 c
之间的差异,将其与 b
和 a
之间的差异进行点积,然后将其除以b
和 a
之间差值的平方。这解决了 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
为了证明这是正确的,让我们画出直线、点和交点:
生成上图的代码是:
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;