在垂直于目标点的3D线上寻找交点 [英] Finding the point of intersection on a 3D line perpendicular to a target point

查看:293
本文介绍了在垂直于目标点的3D线上寻找交点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

c = [50 30 67]; %点

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);
结束


s = round(s);


Z = 100;
N = 100;
X =零(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.-')


轴(N * [0 1 0 1 0 1])$ ​​b $ b网格


解决方案

这需要一些数学来分析。以90度为例,假设您想在此3D线上找到与此线垂直的点,如果将此线从此交点延伸至所需点。



我假设两点 a b 表示三维空间中坐标可以加入它们的坐标, c 是感兴趣的点。以下是我正在谈论的一个更好的图表:



来源: MathWorld



在您的情况下, x1 x2 在您的代码中表示 a b 并且 x0 表示 c 。距离 d 应该是线条上的距离,如果将一条线从交点延伸到点 C

您可以定义一个参数方程,描述 x1 x2 >如此:



x1 x2 之间的这一行上的一个点可以通过将 x1 的每个(x,y,z) x2 并将其写入上面的参数形式,并改变参数 t ,该参数从 [0,1] 。因此, t = 0 会为您提供第一点 x1 a t = 1 会给你第二点 x2 b [0,1] 之间的任何值 t 都会给你一条线。我们的目标是找到最小化距离 x0 的距离的值 t code> c 到这一行。就像我之前说过的,从几何图形我们都知道,如果将一条直线从这个交点延伸到点 x0,那么从一个点到一条直线的最小距离会使相交角垂直/ 90度 c



因此,您所要做的就是找到这个值 t ,然后将其代入上述参数方程中以找到您想要的点。换句话说,我们希望最小化点与线之间的距离,距离可以这样描述:



要找到最小距离,您会发现参数通过找到相对于 t 的导数,并将其设置为0,使上述等式最小化。逻辑上,等式,以便您将距离最小化,而不是距离的平方。然而,将距离平方最小化实际上更容易,这就是为什么上面的等式表示如此。这是有道理的,因为如果你最小化距离的平方....距离也将最小化,因为你只需在答案上放一个平方根就可以得到你要求的东西。如果你这样做,并解决 t ,我们得到这个等式:



因此,找出 a c 之间的区别,take这与点积之间的差异 b a ,然后除以这个差值的幅度平方 b a 。这解决了 t ,然后你可以用它代入上面的参数方程来找到你的观点。



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

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

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

ab = b - a; %//找到x2 - x1

%// - (x1 - x0)。(x2 - x1)/(| x2 - x1 | ^ 2)
t = - (a - c )*(ab。')/(ab * ab。'); %//计算t

%//找到交点
Xinter = a +(b - a)* t;

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

举例来说,我们得到:

  Xinter = 

16.9889 23.7211 76.0539

为了证明这是正确的,让我们画出线,点和点十字路口:





产生上图的代码是:

  figure; 

//绘图线
plot3([a(1)b(1)],[a(2)b(2)],[a(3)b(3) ]);
坚持;

%//红点
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');

%//开启网格
网格;


I have a line and a point and I wanted to find a point (x,y,z) on the line that is 90 degrees or perpendicular if I were to draw a line from this point of intersection with another point.

So far I can create a line with this code and i have another code that calculates angle between three points, but that doesn't really apply here:

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

解决方案

This will require a bit of mathematics to determine that analytically. By "90 degrees", I'm assuming you want to find the point on this 3D line that would be perpendicular to this line if you extended a line from this point of intersection to the desired point.

I'm assuming the two points a and b denote the coordinates in 3D space where a line can join them and that c is the point of interest. Here's a better diagram of what I'm talking about:

Source: MathWorld

In your case, x1 and x2 denote a and b in your code and x0 denotes c. The distance d would be the distance on the line that would allow the point to be perpendicular to this line if you extended a line from the point of intersection to the point c.

You can define a parametric equation that describes the line between x1 and x2 like so:

A point on this line between x1 and x2 can be described by taking each of the (x,y,z) values for x1 and x2 and writing it in the above parametric form and varying the parameter t, which goes from [0,1]. Therefore t=0 would give you the first point x1 or a and t=1 would give you the second point x2 or b. Any value of t between [0,1] would give you a point along the line. The objective is to find the value t that would minimize the distance from x0 or c to this line. Like I said before, we all know from geometry that the smallest distance from a point to a line would make the angle of intersection perpendicular / 90 degrees if you extended a line from this point of intersection to the point x0 or c.

Therefore, all you have to do is find this value of t, then substitute this into the above parametric equation to find your desired point. In other words, we want to minimize the distance between the point and the line, and the distance can be described like so:

To find the minimum distance, you'd find the parameter t that minimized the above equation by finding the derivative with respect to t and setting it equal to 0. Logistically, you would take the square root of the equation so that you would be minimizing the distance, and not the distance squared. However, it's actually easier to minimize the distance squared, which is why the equation above is represented like so. It makes sense because if you minimize the distance squared.... the distance would also be minimized as you'd simply just place a square root on the answer to get what you asked for. Eliminating the square root from the equation would make calculating the derivative easier.

If you do that, and solve for t, we get this equation:

Therefore, find the difference between a and c, take this with the dot product with the difference between b and a, then divide this by the magnitude squared of the difference between b and a. This solves for t, and then you'd substitute this into the above parametric equation to find your point.

In MATLAB code, it could look something like this:

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;

The code for t I took advantage of using matrix multiplication. The dot product can be found by multiplying a row array by a column array and in a similar fashion, if the row array and column array have the same coefficients, this results in the magnitude squared of a vector.

For your example, we get:

Xinter =

   16.9889   23.7211   76.0539

To show that this is right, let's plot the line, and the point and the point of intersection:

The code to produce the above figure is:

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;

这篇关于在垂直于目标点的3D线上寻找交点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆