检查3D点是否位于给定的3D线上(两个3D点之间)

编程入门 行业动态 更新时间:2024-10-24 18:28:57
本文介绍了检查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 任意点 | 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)不在行

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点之间)

本文发布于:2023-07-17 17:10:16,感谢您对本站的认可!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:线上   两个

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!