论文阅读笔记:A Fast Triangle-Triangle Intersection Test

论文:A Fast Triangle-Triangle Intersection Test

作者:Tomas Moller
时间:2012.04.06

1.简介

计算两个三角形是否相交的算法及优化。(碰撞检测算法)

2.介绍

碰撞检测算法:

OBBTree(文章“OBBTree: A Hierarchical Structure for Rapid Interference Detection” Cottschalk 96)
sphere hierarchies (文章“Approximat ing Polyhedra with Spheres for Time-Critical Collision Detection” Hubbard 96)
BV-tress(文章“"Efficient Collision Detection Using Bounding Volume Hierarchies of k-DOPs” Klosowski 97)

3.相测试方法

  • 两个三角形表示:T1T_1,T2T_2;
  • 三角形点:T1T_1V01V_0^1V11V_1^1V21V_2^1T2T_2V02V_0^2V12V_1^2V22V_2^2
  • 三角形所在的面:π1\pi_1,π2\pi_2

第一步:平面π2\pi_2方程: N2X+d2=0N_2·X + d_2 = 0, XX为平面任意一点
其中:N2=(V12V02)×V22V02);N_2 = (V_1^2-V_0^2)×(V_2^2 -V_0^2); d2=N2V02;d_2=-N_2·V_0^2;
第二步:表示T1T_1上点到π2\pi_2的距离
dvi1=N2Vi1+d2,i=0,1,2;d_{v_i^1}=N_2·V_i^1+d_2,i=0,1,2;
第三步:判断
①当dvi10i=0,1,2d_{v_i^1} ≠ 0,i=0,1,2成立,且符号相同,则T1T_1位于π2\pi_2一侧,则不会相交。同理T2T_2,π1\pi_1也可以排除相交情况。这两个拒绝检测可以较早的排除掉许多三角形对。
②当dvi1=0i=0,1,2d_{v_i^1} = 0,i=0,1,2成立,两个三角形共平面,稍后讨论。
③排除上述两种情况,π1\pi_1π2\pi_2相交与一条直线L=O+tDL=O+tD,其中D=N1×N2,线;D=N_1×N_2,为直线方向;OO是线上一点。且可以确定T1T_1,T2T_2均与直线相交,当相交区间有重叠时,可判断两三角形相交。两种情况如图1所示。
论文阅读笔记:A Fast Triangle-Triangle Intersection Test

针对这种情况将需要计算出T1T_1LL上的相交标量区间,我们可以假设V01V_0^1V21V_2^1在同侧,V11V_1^1π2\pi_2另一侧(其他情况①②已排除)。
三角形顶点到直线的投影:pvi1=DVi1O;p_{v_i^1} =D·(V_i^1-O);
几何关系如图2所示。
论文阅读笔记:A Fast Triangle-Triangle Intersection Test

然后我们需要计算线段参数t1t_1,有B=V01V11L=O+t1DB=\overline{V_0^1V_1^1}∩L = O+t_1D
Ki1K_i^1表示Vi1V_i^1π2\pi_2上的投影,我们可以找到相似三角形V01BK01△V_0^1BK_0^1V11BK11△V_1^1BK_1^1。所以t1=pv01+(pv11pv01)dv01dv01dv11; t_1=p_{v_0^1}+(p_{v_1^1}-p_{v_0^1)}\frac{d_{v_0^1}}{d_{v_0^1}-d_{v_1^1}};
同理计算t2t_2,同理T2T_2
如果两个区间重叠,则三角形相交。
回头看②中同面情况,将三角形投影在两三角形面积最大的轴平面,问题转换为二维的三角形重叠测试。首先测试T1T_1中所有的边是否与T2T_2中所有边相交,有相交则两三角形相交成立。否则需要排除包含情况。采用点在三角形中测试(文章"Point in Polygon Strategies"Haines 94),T1T_1T2T_2中以及T2T_2T1T_1中。

4.优化

①由于整体平移不改变相交测试结果,所以计算pvi1p_{v_i^1}可以简化
pvi1=DVi1i=0,1,2;p_{v_i^1} =D·V_i^1,i=0,1,2; OO可以不用计算。
②我们可以将直线LL投影到最一致的轴上(与直线LL夹角最小的轴,即max(Dx,Dy,Dz)max(|D_x|,|D_y|,|D_z|)对应的轴),pvi1p_{v_i^1}计算可以进一步简化
pvi1={Vix1,ifDx=max(Dx,Dy,Dz)Viy1,ifDy=max(Dx,Dy,Dz)Viz1,ifDz=max(Dx,Dy,Dz),i=0,1,2;p_{v_i^1}= \begin{cases}V_{ix}^1,if |D_x| = max(|D_x|,|D_y|,|D_z|) \\V_{iy}^1,if |D_y| = max(|D_x|,|D_y|,|D_z|) \\V_{iz}^1,if |D_z| = max(|D_x|,|D_y|,|D_z|) \end{cases},i=0,1,2;
其中V0x1V_{0x}^1表示V01V_0^1xx方向分量,其它类似。

5.实现和性能

步骤:

①计算T2T_2方程;
②若T1T_1所有点在同侧,返回不相交;
③计算T1T_1方程;
④若T2T_2所有点在同侧,返回不相交;
⑤计算相交直线,并投影到最大轴
⑥计算每个三角形相交区间
⑦区间相交
同面情况很少见,可以放到后面处理。
注意事项:
①点在面上的判断,需要引入固定小值EPSILON(ϵ\epsilon),当距离小于该值是认为,点在面上。
②根据情况判断是否需要考虑三角形退化为直线和点的情况,若需要,不得不优先考虑退化情况。
性能:
Oxygen VR-platform中内部碰撞检测包使用了这个方法。