我在3D空间中有一个三角形ABC,并且在起点E(总是在三角形边缘内部或在三角形边缘上)和方向矢量d给出三角形平面内的光线。
顶点A,B和C以及E和d以3D坐标{x,y,z}给出。
我正在寻找一种算法来计算光线与三角形边缘P的交点。
我可以对三角形的3个边缘进行3次射线/线段交叉测试,但由于我必须为大量三角形做这个,我正在寻找更高效,更快的算法。
答案 0 :(得分:1)
答案 1 :(得分:1)
重心坐标可以帮助吗?
可能。这取决于你的非重心代码有多高度优化,但我说使用重心坐标至少更容易编写既可维护又高效的代码。
据我所知,您的整个设置基本上是2d,E
点和方向d
都包含在A,B,C
所跨越的平面内。你有
E = aE*A + bE*B + cE*C with aE+bE+cE=1
d = ad*A + bd*B + cd*C with ad+bd+cd=0
现在你有两个子问题:
让我们从后者开始吧。您只需将E
的倍数添加到d
,直到c
坐标变为零。
P = E - (cE/cd)*d
根据您的设置,您可能也可以使用齐次坐标,在这种情况下,您可以将其写为P = cd*E - cE*d
。
如何将x,y,z
和d
的{{1}}坐标转换为重心E
?那么,这只是一个线性方程组。您可以使用由向量a,b,c
形成的矩阵的逆矩阵。同样,如果您正在处理齐次坐标,则可以使用adjunct而不是inverse。
这是拼写出来的同质方法:
A,B,C
前三行将aE = (By*Cz-Bz*Cy)*Ex + (Bz*Cx-Bx*Cz)*Ey + (Bx*Cy-By*Cx)*Ez
bE = (Cy*Az-Cz*Ay)*Ex + (Cz*Ax-Cx*Az)*Ey + (Cx*Ay-Cy*Ax)*Ez
cE = (Ay*Bz-Az*By)*Ex + (Az*Bx-Ax*Bz)*Ey + (Ax*By-Ay*Bx)*Ez
ad = (By*Cz-Bz*Cy)*dx + (Bz*Cx-Bx*Cz)*dy + (Bx*Cy-By*Cx)*dz
bd = (Cy*Az-Cz*Ay)*dx + (Cz*Ax-Cx*Az)*dy + (Cx*Ay-Cy*Ax)*dz
cd = (Ay*Bz-Az*By)*dx + (Az*Bx-Ax*Bz)*dy + (Ax*By-Ay*Bx)*dz
aP = cd*aE - cE*ad
bP = cd*bE - cE*bd
Px = aP/(aP+bP)*Ax + bP/(aP+bP)*Bx
Py = aP/(aP+bP)*Ay + bP/(aP+bP)*By
Pz = aP/(aP+bP)*Az + bP/(aP+bP)*Bz
转换为重心坐标,接下来的三行E
。然后我们计算d
的重心坐标,并将它们转回笛卡尔坐标。在那一步中,我们也将它们去均匀化,即除以重心坐标的总和。
总的来说,这里有相当多的代码。您可以通过将常用表达式移动到专用变量来减少操作数,特别是如果您的编译器没有为您执行此操作。一个好处是,除了最终的非均匀化,即除P
之外,你不需要任何划分。如果你计算(a+b)
一次,你可以用一个分区来做,这对性能有好处。
上述代码的真正好处可能是您可以使用重心坐标做很多好事,而这些坐标对于其他坐标系统并不容易。例如,如果要检查光线是否到达线段上的线1/(a+b)
或三角形外的某处,请检查是否AB
。
答案 2 :(得分:1)
暂时忽略d具有最小组件的轴,并处理生成的2D问题,就像我们在插图中看到的那样。
您可以预先计算光线支撑线的方程式,形式为ax + by + c = 0(假设z被忽略)。在此表达式中插入三个顶点的坐标,符号将告诉您顶点的哪一侧。
与线的两个交点出现在端点处具有不同符号的边缘上。
然后,为了确定哪个是右边缘,光线和第三个边缘之间的角度符号会做(如果我是对的);
当您知道哪条边时,您可以计算边的参数方程的参数,您可以从先前计算的符号中推导出该参数。例如,沿着边缘AB,t = Sb /(Sb-Sa)。同时计算1 - t;
最后,使用t值在端点之间进行插值,这次是3D。
计算成本
评估Sa,Sb,Sc三个符号,取6 +和6 x;
选择两个边缘候选者,进行两次或三次比较;
选择单个候选者,采用2D交叉积,3 +和2 x并进行比较;
计算插值参数,2 +,1 /;
最终3D插值,3 +,6 x。
很难做得更短。
答案 3 :(得分:0)
见论文
Fast, minimum storage ray-triangle intersection, 作者:TomasMöller和Ben Trombone, 在 图形工具杂志,2(1):21-28,1997。
另见this page。
作者说:
这种方法的一个优点是平面方程不需要在运行中计算也不需要存储,这可以节省三角网格的显着内存节省。由于我们发现我们的方法在速度上与以前的方法相当,我们认为它是没有预先计算平面方程的三角形中最快的光线 - 三角形交叉例程。