射线与三角形相交检测(最优解)

8 阅读1分钟

常规算法

一种很常规的思路就是先计算射线与三角面的交点,再看该交点是否在三角形内部

快速,最少存储的射线与三角形相交检测

一条射线 R(t),我们可以通过一个起点和一个规一化后的方向量D来定义

R(t)=O+tDt属于实数)R(t)= O + tD (t属于实数)

假设三角形有三个顶点分别用V0,V1,V2V_0, V_1, V_2

假设有一个点 T(u,v)T(u, v) ,在三角形内,那我们就可以用下面的式子表示这个点

T(u,v)=(1uv)V0+uV1+vV2T(u, v) = (1-u-v)V_0 + uV_1 + vV_2

(u,v)(u,v) 是三角形的重心坐标,所以 u0,v0而且u+v1u\ge0, v\ge0 而且 u+v\le 1

结合上面的知识那么射线 R(t)R(t)和三角形 T(u,v)T(u,v) 相交就可以等价于求 R(t)=T(u,v)R(t)=T(u,v),我们就会得到下面的方程

O+tD=(1uv)V0+uV1+vV2O+tD=(1-u-v)V_0 + uV_1 + vV_2

整理上面的方法我们会得到这样一个线性方程

[D,V1V0,V2V0][tuv]=OV0(4)\begin{bmatrix} -D, & V_1 - V_0, & V_2 - V_0 \end{bmatrix} \begin{bmatrix} t \\ u \\ v \end{bmatrix} = O - V_0 \tag{4}

我们用E1=V1v0,E2=v2v0T=OV0E_1=V_1-v_0, E_2=v_2-v_0, T=O-V_0, (4)式经过 克莱姆法则我们可以得到如下矩阵表达

[tuv]=1D, E1, E2[T,E1,E2D,T,E2D,E1,T](5)\begin{bmatrix} t \\ u \\ v \end{bmatrix} = \frac{1}{\left| -D,\ E_1,\ E_2 \right|} \begin{bmatrix} T, & E_1, & E_2 \\ -D, & T, & E_2 \\ -D, & E_1, & T \end{bmatrix} \tag{5}

根据线性方程,我们可以知道 A, B, C=(A×B)C=(A×C)B=(C×B)A\left| A,\ B,\ C \right|= (A \times B) \cdot C = -(A \times C) \cdot B = -(C \times B) \cdot A,经过变换方程(5)可以变换成下列方程,其中 P=(D×E2),Q=T×E1P=(D \times E_2), Q=T \times E_1

[tuv]=1(D×E2)E1[(T×E1)E2(D×E2)T(T×E1)D]=1PE1[QE2PTQD],(6)\begin{bmatrix} t \\ u \\ v \end{bmatrix} = \frac{1}{(D \times E_2) \cdot E_1} \begin{bmatrix} (T \times E_1) \cdot E_2 \\ (D \times E_2) \cdot T \\ (T \times E_1) \cdot D \end{bmatrix} = \frac{1}{P \cdot E_1} \begin{bmatrix} Q \cdot E_2 \\ P \cdot T \\ Q \cdot D \end{bmatrix}, \tag{6}

通过解上面的线性方程我们就可以分别求得 u,v,tu, v, t 的值,如果不在允许的范围内,则可以判定射线与三角形不相交。

论文参考 Fast,Minimum Storage Ray & Triangle Intersection

克莱姆解线性方程组可以查阅文章:克莱姆法则

三矢量的混合积:矢量混合积

注:下节我会结合 Threejs 的源码来解答此方程在工程上的实际应用问题