Möller-Trumbore算法
一、概述
Möller-Trumbore 射线三角相交算法是一种快速计算射线与三角形在三个维度上的交点的方法,通过向量与矩阵计算可以快速得出交点与重心坐标,而无需对包含三角形的平面方程进行预计算。另外,它还应用于计算机图形学中以实现涉及三角形网格的光线跟踪计算。算法名字是以发明者 TomasMöller 和 Ben Trumbore 的名字来命名的。
二、准备知识
1、三阶方阵的行列式等于三个列向量的混合积
2、克莱姆法则(部分译克拉默法则)
如果一个线性方程组
A
x
=
c
\boldsymbol{Ax} = \boldsymbol{c}
Ax=c, 其中
A
\boldsymbol{A}
A 是可逆方阵,
x
\boldsymbol{x}
x,
c
\boldsymbol{c}
c 都是列向量,那么方程有解,且
x
\boldsymbol{x}
x 的每一个解
其中 A i A_i Ai 是被列向量取代了第 i i i 列的矩阵。
三、Möller-Trumbore 算法推导
已知光线
R
a
y
=
O
+
t
D
\boldsymbol{Ray} = \boldsymbol{O} + t\boldsymbol{D}
Ray=O+tD(
O
\boldsymbol{O}
O 为起点,
D
\boldsymbol{D}
D为射线方向,
t
t
t 为时间), 三角形三个顶点
P
0
P_0
P0,
P
1
P_1
P1,
P
2
P_2
P2。 光线与三角形相交时,可得如下等式:
则可以解
参数定义:
推导过程
从这里开始
括号展开,移项可得
观察一下上面的括号以及等式左边的内容,都是已知的点,因此点的加减可以用向量来表示,令
得到
也即
这是一个形如
A
x
=
c
\boldsymbol{Ax} = \boldsymbol{c}
Ax=c 的等式,所以可以用克拉莫法则
由向量混合积可以得出
分母部分:
令
原式等于
分子部分:
令
原式等于
因此
另外的两个参数
b
1
b_1
b1,
b
2
b_2
b2可以同样推出来
四、代码实现
bool rayTriangleIntersect(const Vector3f& v0, const Vector3f& v1, const Vector3f& v2, const Vector3f& orig,
const Vector3f& dir, float& tnear, float& u, float& v)
{
bool isIn = false;
Vector3f E1 = v1 - v0;
Vector3f E2 = v2 - v0;
Vector3f S = orig - v0;
Vector3f S1 = crossProduct(dir, E2);
Vector3f S2 = crossProduct(S, E1);
float coeff = 1.0 / dotProduct(S1, E1); // 共同系数
float t = coeff * dotProduct(S2, E2);
float b1 = coeff * dotProduct(S1, S);
float b2 = coeff * dotProduct(S2, dir);
if (t >= 0 && b1 >= 0 && b2 >= 0 && (1 - b1 - b2) >= 0)
{
isIn = true;
tnear = t;
u = b1;
v = b2;
}
return isIn;
}
参考资料
[1] 直线与三角形相交Moller Trumbore算法推导:
https://www.blurredcode.com/2020/04/%E7%9B%B4%E7%BA%BF%E4%B8%8E%E4%B8%89%E8%A7%92%E5%BD%A2%E7%9B%B8%E4%BA%A4moller-trumbore%E7%AE%97%E6%B3%95%E6%8E%A8%E5%AF%BC/
[2] 克莱姆法则:https://zh.wikipedia.org/wiki/%E5%85%8B%E8%90%8A%E5%A7%86%E6%B3%95%E5%89%87
[3] Möller–Trumbore 算法:https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm
[4] 行列式的几何意义:https://www.cnblogs.com/andyjee/p/3491487.html
欢迎关注个人公众号,实时推送最新博文!