常规算法
一种很常规的思路就是先计算射线与三角面的交点,再看该交点是否在三角形内部
快速,最少存储的射线与三角形相交检测
一条射线 R(t),我们可以通过一个起点和一个规一化后的方向量D来定义
R(t)=O+tD(t属于实数)
假设三角形有三个顶点分别用V0,V1,V2 。
假设有一个点 T(u,v) ,在三角形内,那我们就可以用下面的式子表示这个点
T(u,v)=(1−u−v)V0+uV1+vV2
(u,v) 是三角形的重心坐标,所以 u≥0,v≥0而且u+v≤1。
结合上面的知识那么射线 R(t)和三角形 T(u,v) 相交就可以等价于求 R(t)=T(u,v),我们就会得到下面的方程
O+tD=(1−u−v)V0+uV1+vV2
整理上面的方法我们会得到这样一个线性方程
[−D,V1−V0,V2−V0]tuv=O−V0(4)
我们用E1=V1−v0,E2=v2−v0,T=O−V0, (4)式经过 克莱姆法则我们可以得到如下矩阵表达
tuv=∣−D, E1, E2∣1T,−D,−D,E1,T,E1,E2E2T(5)
根据线性方程,我们可以知道 ∣A, B, C∣=(A×B)⋅C=−(A×C)⋅B=−(C×B)⋅A,经过变换方程(5)可以变换成下列方程,其中 P=(D×E2),Q=T×E1
tuv=(D×E2)⋅E11(T×E1)⋅E2(D×E2)⋅T(T×E1)⋅D=P⋅E11Q⋅E2P⋅TQ⋅D,(6)
通过解上面的线性方程我们就可以分别求得 u,v,t 的值,如果不在允许的范围内,则可以判定射线与三角形不相交。
论文参考 Fast,Minimum Storage Ray & Triangle Intersection
克莱姆解线性方程组可以查阅文章:克莱姆法则
三矢量的混合积:矢量混合积
注:下节我会结合 Threejs 的源码来解答此方程在工程上的实际应用问题