PaperRead - A fast triangle-triangle intersection test
Moller T. A fast triangle-triangle intersection test[J]. Journal of Graphics Tools, 1997, 2(2): 25-30.
来描述下已知条件:
- 三角形\(T_1\)和\(T_2\);
- 三角形\(T_1\)的顶点为\(V_0^1,V_1^1,V_2^1\),三角形\(T_2\)的顶点为\(V_0^2,V_1^2,V_2^2\);
- 三角形\(T_1\)所在的平面为\(\pi_1\);三角形\(T_2\)所在的平面为\(\pi_2\)。
首先确定平面\(\pi_2\)的方程如下:
其中X是平面上的任意一点,\(N_2\)和\(d_2\)如下:
上面公式就是平面方程的一般形式,可以写成如下形式,更加容易理解:
那么三角形\(T_1\)的三个顶点到平面\(\pi_2\)的距离可以通过带入上面的公式直接计算得到,如下:
如果\(d_{V_i^1} \ne 0\),并且所有的值都有相同的符号,那么三角形\(T_1\)位于平面\(\pi_2\)的一侧,那么三角形之间是没有交叠的;对于三角形\(T_2\)和平面\(\pi_1\)也用相同的处理方式。
如果所有的\(d_{V_i^1} = 0\),那么三角形是共面的;如果不是,那么平面\(\pi_1\)和\(\pi_2\)相交一条线,\(L = O + tD\),其中\(D = N_1 \times N_2\)是线的方向,\(O\)是线上的一个点。如果相交的线段有重叠,那么两个三角形相交,如下图。
直线L与三角形,相交段计算。假设我们需要计算三角形\(T_1\)和直线\(L\)之间的相交线段,假设\(V_0^1\)和\(V_2^1\)位于平面\(\pi_2\)的同一侧,\(V_1^1\)位于平面的另一侧。先将顶点投影到直线L上,如下:
从上图可见,三角形\(V_0^1BK_0^1\)和三角形\(V_1^1BK_1^1\)相似。那么可以得到:
同理可得t2,同理可以得到三角形\(T_2\)上的相交线段。
如果两个线段有重叠,那么两个三角形相交。
如果两个三角形共面。那么将三角形投影到能够得到最大面积的axis-aligned plane上。接下来执行二维三角形相交测试即可。
优化
由于L线上的重叠关系是针对线段区间的,只针对相交测试的话,求\(p_{V_i^1}\)的公式可以简化为:
又由于重叠关系在投影到最近的一条轴上的时候,仍然保留,因此可以进一步简化为:
小结
整个算法流程如下:
- 计算三角形2的平面方程;
- 如果三角形1的顶点都在三角形2的同一侧,那么不相交;
- 计算三角形1的平面方程;
- 如果三角形2的顶点都在三角形1的同一侧,那么不相交;
- 计算两个平面的相交线,并投影到最大的轴上;
- 计算相交线和每个三角形的相交的线段;
- 判断两个三角形的上相交的线段之间的关系;
目前算法对于三角形退化成直线或点的情况没有考虑。
Others
其他类似的判断三角形相交的算法见:快速检测空间三角形相交算法的代码实现(Devillers & Guigue算法)
作者: grassofsky
出处: http://www.cnblogs.com/grass-and-moon
本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出, 原文链接 如有问题, 可邮件(grass-of-sky@163.com)咨询.
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步