我有两个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)不在行 $ c $点积的结果给出了一个向量投影到另一个向量的比例,或者它们之间的角度的cos(如果它们被归一化)因此对于并行向量,结果是长度 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.0to 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 lineAs 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.0So:
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 linebtw 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点之间)
发布评论