检查3D点是否位于给定的3D线上(两个3D点之间) [英] Check if a 3D Point lies on a given 3D line(between two 3D Points)

查看:346
本文介绍了检查3D点是否位于给定的3D线上(两个3D点之间)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个3D点,即(x1,y1,z1)和(x2,y2,z2)以及3D点(x,y,z)。
我想知道是否(x,y,z)位于连接(x1,y1,z1)和(x2,y2,z2)的连线上。



  if(((((x  -  x1)/ x2-x1)==( (y-y1)/ y2-y1))&&(((x-x1)/ x2-x1)
==((z-z1)/ z2- z1)) - > ,3D线相交(x,y,z)

但是,如果我的x1 = x2(或者)y1 = y2(或)z1 = z2?那么我会收到一个错误,说除以零是不可能的。

我会很高兴,如果有人可以提出一些替代方法。



在此先感谢。

解决方案

简单的点积可以很容易地做到这一点...所以让我们考虑一下 line 定义了两个点 p0,p1 任意点<$ c












$ b pre> | dot(p1-p0,p-p0)| /(| p1-p0 | * | p-p0 |)= 1.0

使它更像浮点数比较稳健:

  | dot(p1-p0,p- p0)| /(| p1-p0 | * | p-p0 |)> = 1.0-1e-10; 

其中 1e-10 足够小epsilon ...重写为代码:

  dx = x1-x0; 
dy = y1-y0;
dz = z1-z0;

ex = x-x0;
ey = y-y0;
ez = z-z0;

q = dx * ex;
q + = dy * ey;
q + = dz * zy;
q * = q;
q / =(dx * dx + dy * dy + dz * dz);
q / =(ex * ex + ey * ey + ez * ez);

如果(q> = 1.0-1e-10)点p(x,y)在行
else p(x,y)不在行

正如你所看到的,没有必要使用sqrt,我们可以比较它的功耗......



然而,如果 p == p0 然后使用 p1 或返回真正的马上。



如果你只想在线段内(不在边缘点之外),那么你需要稍微改变代码

  0.0 <= dot(p1-p0,p-p0)/ | p-p0 | < = 1.0 

所以:

  DX = X1-X0; 
dy = y1-y0;
dz = z1-z0;

ex = x-x0;
ey = y-y0;
ez = z-z0;

q = dx * ex;
q + = dy * ey;
q + = dz * zy;如果(q <0.0)p(x,y)不在线上,
;
q * = q;
q / =(ex * ex + ey * ey + ez * ez);

if(q <= 1.0)point p(x,y)在行
else p(x,y)不在行
100%
1.0 。如果您使用测角和 p-p0 调整 1e-10 值,则可以将其转换为检测点与线的垂直距离(这可能对于粗线和鼠标选择而言得心应手)。

I have two 3D Points viz. (x1,y1,z1) and (x2,y2,z2) and a 3D Point (x,y,z). I would like to know if (x,y,z) lies on the line connecting (x1,y1,z1) and (x2,y2,z2).

I tried the following algorithm:

    if ((((x - x1) / x2-x1) == ((y - y1) / y2-y1)) && (((x - x1) / x2 - x1) 
== ((z - z1) / z2- z1)) --> then,the 3D Line intersects (x,y,z)

But,what if my x1 = x2 (or) y1 = y2 (or) z1=z2? Then I would be getting an error saying "Division by zero" is not possible.

I would be glad,if someone can propose some alternative method.

Thanks in Advance.

解决方案

simple dot product can do this easily ... so let consider we got line defined by two points p0,p1. Any point p on that line will have the same or negative slope to any of the endpoints so

|dot(p1-p0,p-p0)|/(|p1-p0|*|p-p0|) = 1.0

to make it more robust with floating point compare like this:

|dot(p1-p0,p-p0)|/(|p1-p0|*|p-p0|) >= 1.0-1e-10;

Where 1e-10 is small enough epsilon ... rewriten to code:

dx=x1-x0;
dy=y1-y0;
dz=z1-z0; 

ex=x-x0;
ey=y-y0;
ez=z-z0;

q =dx*ex;
q+=dy*ey;
q+=dz*zy;
q*=q;
q/=(dx*dx+dy*dy+dz*dz);
q/=(ex*ex+ey*ey+ez*ez);

if (q>=1.0-1e-10) point p(x,y) is on the line
 else p(x,y) is not on line

As you can see no need for the sqrt we can compare the power instead ...

However you should handle edge case when p==p0 then either use p1 or return true right away.

In case you want points only inside the line segment (not outside the edge points) then you need a slight change in code

0.0 <= dot(p1-p0,p-p0)/|p-p0| <= 1.0

So:

dx=x1-x0;
dy=y1-y0;
dz=z1-z0; 

ex=x-x0;
ey=y-y0;
ez=z-z0;

q =dx*ex;
q+=dy*ey;
q+=dz*zy;
if (q<0.0) p(x,y) is not on line
q*=q;
q/=(ex*ex+ey*ey+ez*ez);

if (q<=1.0) point p(x,y) is on the line
 else p(x,y) is not on line

btw the result of the dot product gives you ratio of one vector projected to another perpendicularly or cos of the angle between them (if they are normalized) so for parallel vectors the result is 100% of length or 1.0. If you tweak the 1e-10 value using goniometry and p-p0 you can convert this to detect points up to some perpendicular distance to line (which might get handy for thick lines and or mouse selecting).

这篇关于检查3D点是否位于给定的3D线上(两个3D点之间)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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