AABB与Triangle求交
AABB
与三角形求交,采用分离轴的方式实现的一种比较优质的方法。
0. 预备知识
点到面的距离方程
面的方程
- 定义平面
A
的法向 \(\vec{n}\){a,b,c}
, - 已知平面行一点\(P_0 \lbrace x_0,y_0,z_0\rbrace\)
- 任意点 \(P\)
{x,y,z}
- 面方程:
- \(\overrightarrow{P - P_0} \cdot \vec{n} = 0\)
点到面的距离
法向量法
- \(\vec{n}\) - 平面的法向量
- \(d\) - 点到平面的距离
- \(P\) - 平面外一点
- \(A\) - 平面上一点
- $d = $
- PA在法向方向上的投影既是点\(P\)到平面的距离
射线的方程
- 射线方程
- \(O\) 为起点, 沿着方向 \(\vec{d}\)
- 射线方向上任意一点\(P_0\)
- \(P_0 = O + \vec{d}\)
三角形与AABB求交
- 我们定义一个轴对齐包围盒
- center \(c\),
AABB
的中心点 - a half vector \(\vec{h}\), 记录盒子的各个轴的方向与在轴所在方向大小
- center \(c\),
- 一个三角形
- \(\Delta u_0u_1u_2\)
1. 第一步
- 移动
AABB
与三角形,使AABB
与原点重合
2. 计算测试的轴
- 我们将在原点进行基于分离轴的相交测试,需要测试13根轴。
2.1 AABB
的面的法线
- \(\vec{e_0}(1,0,0)\)
- \(\vec{e_1}(0,1,0)\)
- \(\vec{e_2}(0,0,1)\)
2.2 三角形\(\Delta u_0u_1u_2\)的法线
- \(\vec{n}\)
- \(\vec{n} == \vec{f_0} \times \vec{f_1}\)
2.3 \(a_{ij} = e_i \times f_j\)
- \(i,j \in \left ( 0,1,2 \right )\)
- \(\vec{f_0} = \vec{v_1} - \vec{v_0}\)
- \(\vec{f_1} = \vec{v_2} - \vec{v_1}\)
- \(\vec{f_0} = \vec{v_0} - \vec{v_2}\)
3 分离轴计算
一旦找到分离轴算法就会立即停止并且返回一个不相交的结果
如果通过所有的测试并且没有找到分离轴,那么三角形与
AABB box
相交将三角形的顶点投影到每一个分离轴上,然后计算
AABB
在分离轴上的范围,AABB
被移动到原点,它的投影将会是一个\(\left [ -r,+r\right ]\)对称的- 如果她们在这个分离轴上重合,那么它们投影后的结果也是重合的
只有当所有的分离轴上的测试都通过的时候才能是相交的。
Code
define AABB
1 | struct AABB |
define Triangle
1 | struct Triangle |
实现
1 | // done |