其实就是Möller–Trumbore 相交算法,下面是我自己的推导。
三角形三个顶点设为 \vec{V}_{0}, \vec{V}_{1}, \vec{V}_{2},摄像机的起点和方向设为 \vec{O}, \vec{D}。
三角形内任意一点用三角形重心坐标表示:
\vec{P} = (1 - u - v) \vec{V}_{0} + u \vec{V}_{1} + v \vec{V}_{2} (u \ge 0 \ v \ge 0 \ (u + v) \le 1)
\vec{P} = \vec{V}_{0} - u \vec{V}_{0} + u \vec{V}_{1} - v \vec{V}_{0} + v \vec{V}_{2}
\vec{P} = \vec{V}_{0} - u (\vec{V}_{0} - u \vec{V}_{1}) - v (\vec{V}_{0} - v \vec{V}_{2})
我们令 \vec{E}_{1} = \vec{V}_{0} - \vec{V}_{1}, \vec{E}_{2} = \vec{V}_{0} - \vec{V}_{2},式子变为:
\vec{P} = \vec{V}_{0} - u \vec{E}_{1} - v \vec{E}_{2}
摄像机发出的一条条射线用射线方程写为:
\vec{Cam} = \vec{O} + t \vec{D} (t \ge 0)
当摄像机发出的射线击中三角形时,公式可写为:
\vec{P} = \vec{Cam}
\vec{V}_{0} - u \vec{E}_{1} - v \vec{E}_{2} = \vec{O} + t \vec{D}
\vec{V}_{0} - \vec{O} = u \vec{E}_{1} + v \vec{E}_{2} + t \vec{D}
令 \vec{S} = \vec{V}_{0} - \vec{O}
u \vec{E}_{1} + v \vec{E}_{2} + t \vec{D} = \vec{S}
我们逐个去解u , v, t。
首先是u, 我们可以根据叉积的性质,去消掉无关项:
u \vec{E}_{1} \cdot (\vec{E}_{2} \times \vec{D}) + v \vec{E}_{2} \cdot (\vec{E}_{2} \times \vec{D}) + t \vec{D} \cdot (\vec{E}_{2} \times \vec{D}) = \vec{S} \cdot (\vec{E}_{2} \times \vec{D})
u \vec{E}_{1} \cdot (\vec{E}_{2} \times \vec{D}) = \vec{S} \cdot (\vec{E}_{2} \times \vec{D})
u = \frac{\vec{S} \cdot (\vec{E}_{2} \times \vec{D})}{\vec{E}_{1} \cdot (\vec{E}_{2} \times \vec{D})}
同样的,v也是如此:
u \vec{E}_{1} \cdot (\vec{E}_{1} \times \vec{D}) + v \vec{E}_{2} \cdot (\vec{E}_{1} \times \vec{D}) + t \vec{D} \cdot (\vec{E}_{1} \times \vec{D}) = \vec{S} \cdot (\vec{E}_{1} \times \vec{D})
v \vec{E}_{2} \cdot (\vec{E}_{1} \times \vec{D}) = \vec{S} \cdot (\vec{E}_{1} \times \vec{D})
v = \frac{\vec{S} \cdot (\vec{E}_{1} \times \vec{D})}{\vec{E}_{2} \cdot (\vec{E}_{1} \times \vec{D})}
然后是t:
u \vec{E}_{1} \cdot (\vec{E}_{1} \times \vec{E}_{2}) + v \vec{E}_{2} \cdot (\vec{E}_{1} \times \vec{E}_{2}) + t \vec{D} \cdot (\vec{E}_{1} \times \vec{E}_{2}) = \vec{S} \cdot (\vec{E}_{1} \times \vec{E}_{2})
t \vec{D} \cdot (\vec{E}_{1} \times \vec{E}_{2}) = \vec{S} \cdot (\vec{E}_{1} \times \vec{E}_{2})
t = \frac{\vec{S} \cdot (\vec{E}_{1} \times \vec{2})}{\vec{D} \cdot (\vec{E}_{1} \times \vec{E}_{2})}
我们把 \vec{D} \cdot (\vec{E}_{1} \times \vec{E}_{2}) 展开:
\vec{D} \cdot (\vec{E}_{1} \times \vec{E}_{2}) = \\ D.x \cdot E_{1}.y \cdot E_{2}.z - D.x \cdot E_{2}.y \cdot E_{1}.z + \\ D.y \cdot E_{2}.x \cdot E_{1}.z - D.y \cdot E_{1}.x \cdot E_{2}.z + \\ D.z \cdot E_{1}.x \cdot E_{2}.y - D.z \cdot E_{2}.x \cdot E_{1}.y
想必你一定看出什么来了,如果你还看不出来,那么再把式子化为这样:
\vec{D} \cdot (\vec{E}_{1} \times \vec{E}_{2}) = \\ D.x \cdot (E_{1}.y \cdot E_{2}.z - \cdot E_{2}.y \cdot E_{1}.z) \\ - D.y \cdot ( D.y \cdot E_{1}.x \cdot E_{2}.z - E_{2}.x \cdot E_{1}.z) \\ + D.z \cdot ( E_{1}.x \cdot E_{2}.y - \cdot E_{2}.x \cdot E_{1}.y)
根据行列式的拉普拉斯展开,我们可以得到行列式:
\begin{vmatrix}
D.x & D.y & D.z \\
E_{1}.x & E_{1}.y & E_{1}.z \\
E_{2}.x & E_{2}.y & E_{2}.z
\end{vmatrix}
我们对换第一行和第二行,第二行和第三行,再重复刚刚的对换就可以得到:
\begin{vmatrix}
D.x & D.y & D.z \\
E_{1}.x & E_{1}.y & E_{1}.z \\
E_{2}.x & E_{2}.y & E_{2}.z
\end{vmatrix}
=
\begin{vmatrix}
E_{1}.x & E_{1}.y & E_{1}.z \\
E_{2}.x & E_{2}.y & E_{2}.z\\
D.x & D.y & D.z
\end{vmatrix}
=
\begin{vmatrix}
E_{2}.x & E_{2}.y & E_{2}.z\\
D.x & D.y & D.z\\
E_{1}.x & E_{1}.y & E_{1}.z
\end{vmatrix}
于是,我们就可以得到:
\vec{D} \cdot (\vec{E}_{1} \times \vec{E}_{2}) = \vec{E}_{1} \cdot (\vec{E}_{2} \times \vec{D}) = \vec{E}_{2} \cdot (\vec{D} \times \vec{E}_{1})
我们直接令上面的结果为det,于是我们便可得到u, v, t:
u = \frac{\vec{S} \cdot (\vec{E}_{2} \times \vec{D})}{det} \\
v = \frac{\vec{S} \cdot (\vec{E}_{1} \times \vec{D})}{\vec{E}_{2} \cdot (\vec{E}_{1} \times \vec{D})} = \frac{\vec{S} \cdot (\vec{D} \times \vec{E}_{1})}{\vec{E}_{2} \cdot (\vec{D} \times \vec{E}_{1})} = \frac{\vec{S} \cdot (\vec{D} \times \vec{E}_{1})}{det} \\
t = \frac{\vec{S} \cdot (\vec{E}_{1} \times \vec{E}_{2})}{det}
--2026/6/13