参考:
[1] 3D空间中射线与AABB包围盒的碰撞检测
原本打算解决“判断与立方体是否相交”的问题,自然的想法是分别判断线段是否与立方体的六个面相交;此外还查得Slabs方法,简介如下:
- 基本思想:射线穿过立方体的部分 是 六个面中 与两两(无限)平面相交部分的 交。
- (适用于axis-aligned-bounding-box (AABB立方体))
2-D空间为例:射线是否穿过矩形
射线穿过的部分为 x-slab和y-slab之间的线段部分的交
数学表达
- 射线上任意一点表示为: P ⃗ = P ⃗ s t a r t + t ∗ D ⃗ , ( t ⩾ 0 ) \vec{P}=\vec{P}_{start}+t*\vec{D},(t\geqslant0) P=Pstart+t∗D,(t⩾0)
- 射线与x-slab的两个交点为: P ⃗ s t a r t + t x , n e a r ∗ D ⃗ \vec{P}_{start}+t_{x,near}*\vec{D} Pstart+tx,near∗D, P ⃗ s t a r t + t x , n e a r ∗ D ⃗ \vec{P}_{start}+t_{x,near}*\vec{D} Pstart+tx,near∗D;
与y-slab的两个交点为 P ⃗ s t a r t + t y , n e a r ∗ D ⃗ \vec{P}_{start}+t_{y,near}*\vec{D} Pstart+ty,near∗D, P ⃗ s t a r t + t y , f a r ∗ D ⃗ \vec{P}_{start}+t_{y,far}*\vec{D} Pstart+ty,far∗D
- 则是否相交的判断为: m a x ( t x , n e a r , t y , n e a r ) ⩽ m i n ( t x , f a r , t y , f a r ) max(t_{x,near},t_{y,near})\leqslant min(t_{x,far},t_{y,far}) max(tx,near,ty,near)⩽min(tx,far,ty,far) 且 t x , n e a r , t y , n e a r , t x , f a r , t y , f a r ⩾ 0 t_{x,near},t_{y,near},t_{x,far},t_{y,far}\geqslant0 tx,near,ty,near,tx,far,ty,far⩾0
- 若将射线改为线段,在给定 P ⃗ s t a r t , P ⃗ e n d \vec{P}_{start},\vec{P}_{end} Pstart,Pend的情况下, D ⃗ = P ⃗ e n d − P ⃗ s t a r t \vec{D}=\vec{P}_{end}-\vec{P}_{start} D=Pend−Pstart,则 0 ⩽ t ⩽ 1 0\leqslant t \leqslant 1 0⩽t⩽1;只需将上述条件改写为 m a x ( t x , n e a r , t y , n e a r , 0 ) ⩽ m i n ( t x , f a r , t y , f a r , 1 ) max(t_{x,near},t_{y,near},0)\leqslant min(t_{x,far},t_{y,far},1) max(tx,near,ty,near,0)⩽min(tx,far,ty,far,1)
3-D空间:射线是否穿过立方体
同样地,射线穿过的部分为x-slab,y-slab,z-slab 中线段的交
求t的方法
- 假设立方体由bounding box (包围盒): x m i n , y m i n , z m i n , x m a x , y m a x , z m a x x_{min},y_{min},z_{min},x_{max},y_{max},z_{max} xmin,ymin,zmin,xmax,ymax,zmax限定;
- 则射线与立方体中的(无限)平面
X
=
x
m
i
n
X=x_{min}
X=xmin的交点可通过
P ⃗ s t a r t + t ∗ D ⃗ = [ x m i n , 0 , 0 ] T \vec{P}_{start}+t*\vec{D}=[x_{min},0,0]^T Pstart+t∗D=[xmin,0,0]T解得;只求取系数t时可只解其x分量部分,即 x s t a r t + t ∗ d x = x m i n x_{start}+t*d_x=x_{min} xstart+t∗dx=xmin - 同样地,可求得
t
x
,
f
a
r
,
t
y
,
n
e
a
r
,
t
y
,
f
a
r
,
t
z
,
n
e
a
r
,
t
z
,
f
a
r
t_{x,far},t_{y,near},t_{y,far},t_{z,near},t_{z,far}
tx,far,ty,near,ty,far,tz,near,tz,far,判断是否相交的条件为
m a x ( t x , n e a r , t y , n e a r , t z , n e a r ) ⩽ m i n ( t x , f a r , t y , f a r , t z , f a r ) max(t_{x,near},t_{y,near},t_{z,near})\leqslant min(t_{x,far},t_{y,far},t_{z,far}) max(tx,near,ty,near,tz,near)⩽min(tx,far,ty,far,tz,far)
Remarks
平行于某平面
当射线平行于某平面时,可以直接判断射线是否在平面外,例如:
射线平行于 Y O Z YOZ YOZ平面,可以判断 :
- 若 x < x m i n x<x_{min} x<xmin或 x > x m a x x>x_{max} x>xmax则可直接断定不相交;
- 若 x ⩾ x m i n x\geqslant x_{min} x⩾xmin且 x ⩽ x m a x x\leqslant x_{max} x⩽xmax,则可正常交由 m a x ( t y , n e a r , t z , n e a r ) ⩽ m i n ( t y , f a r , t z , f a r ) max(t_{y,near},t_{z,near})\leqslant min(t_{y,far},t_{z,far}) max(ty,near,tz,near)⩽min(ty,far,tz,far)判断是否相交;
平行于坐标轴
与平行于某平面类似
- 通过判断与立方体边界的位置关系直接断定是否不相交;
- 若无法断定,则正常交由 剩余一轴的 m a x ( t n e a r ) ⩽ m i n ( t f a r ) max(t_{near})\leqslant min(t_{far}) max(tnear)⩽min(tfar)判断
射线 V.S 线段
按先前的定义,射线中,系数 t ⩾ 0 t\geqslant 0 t⩾0;线段中,系数 t ∈ [ 0 , 1 ] t \in [0,1] t∈[0,1]。
区分 t n e a r , t f a r t_{near},t_{far} tnear,tfar
- 异号:若起始点 P s t a r t P_{start} Pstart不在立方体内,则 t n e a r , t f a r t_{near},t_{far} tnear,tfar不会出现异号的情况;
- 同正:只需将取值小的 t t t作为 t n e a r t_{near} tnear,将取值大的 t t t作为 t f a r t_{far} tfar即可;
- 同负:由于射线和线段的定义中都要求 t ⩾ 0 t \geqslant 0 t⩾0,则出现同负情况下可直接断定射线/线段与立方体不相交。