0%

03 - 在 3D 中两条射线的相交性检测

在 3D 中两条射线的相交性检测

令 3D 中两条以参数形式定义的射线:

{r1(t1)=p1+t1d1r2(t2)=p2+t2d2\begin{cases} \bold{r_1}(t_1) = \bold{p_1} + t_1 \bold{d_1} \\[1.5ex] \bold{r_2}(t_2) = \bold{p_2} + t_2 \bold{d_2} \end{cases}

暂时不考虑 t1t_1t2t_2 的取值范围,即考虑的是无限长的射线;
并且其中向量 d1d_1d2d_2 不必是单位向量。

若这两条射线在一个平面中,则跟 2D 中的直线相交的情况相同:

  • 两条射线交于一点;
  • 两条射线平行,没有交点;
  • 两条射线重合,有无限多交点。

在三维空间中,存在第四种可能性:

  • 两条射线不在一个平面中

推导过程:

r1(t1)=r2(t2)p1+t1d1=p2+t2d2t1d1=p2+t2d2p1(t1d1)×d2=(p2+t2d2p1)×d2t1(d1×d2)=(t2d2)×d2+(p2p1)×d2t1(d1×d2)=t20+(p2p1)×d2t1(d1×d2)=(p2p1)×d2t1(d1×d2)(d1×d2)=((p2p1)×d2)(d1×d2)\begin{aligned} \bold{r_1}(t_1) &= \bold{r_2}(t_2) \\[1.5ex] \bold{p_1} + t_1 \bold{d_1} &= \bold{p_2} + t_2 \bold{d_2} \\[1.5ex] t_1 \bold{d_1} &= \bold{p_2} + t_2 \bold{d_2} - \bold{p_1} \\[1.5ex] (t_1 \bold{d_1}) \times \bold{d_2} &= (\bold{p_2} + t_2 \bold{d_2} - \bold{p_1}) \times \bold{d_2} \\[1.5ex] t_1 (\bold{d_1} \times \bold{d_2}) &= (t_2 \bold{d_2}) \times \bold{d_2} + (\bold{p_2} - \bold{p_1}) \times \bold{d_2} \\[1.5ex] t_1 (\bold{d_1} \times \bold{d_2}) &= t_2 \cdot \bold{0} + (\bold{p_2} - \bold{p_1}) \times \bold{d_2} \\[1.5ex] t_1 (\bold{d_1} \times \bold{d_2}) &= (\bold{p_2} - \bold{p_1}) \times \bold{d_2} \\[1.5ex] t_1 (\bold{d_1} \times \bold{d_2}) \cdot (\bold{d_1} \times \bold{d_2}) &= ((\bold{p_2} - \bold{p_1}) \times \bold{d_2}) \cdot (\bold{d_1} \times \bold{d_2}) \end{aligned}

可得:

t1=((p2p1)×d2)(d1×d2)d1×d22t_1 = \cfrac{((\bold{p_2} - \bold{p_1}) \times \bold{d_2}) \cdot (\bold{d_1} \times \bold{d_2})}{\Vert {\bold{d_1} \times \bold{d_2}} \Vert^2}

同理:

t2=((p2p1)×d1)(d1×d2)d1×d22t_2 = \cfrac{((\bold{p_2} - \bold{p_1}) \times \bold{d_1}) \cdot (\bold{d_1} \times \bold{d_2})}{\Vert {\bold{d_1} \times \bold{d_2}} \Vert^2}

NOTE

  • d1×d2=0\bold{d_1} \times \bold{d_2} = 0 :两条射线平行或者重合,即上式的分母为零。
     
  • 若两条射线在一个平面内,那么 r1(t1)\bold{r_1}(t_1)r2(t2)\bold{r_2}(t_2) 是相距最近的点。
    • 通过检查 r1(t1)\bold{r_1}(t_1)r2(t2)\bold{r_2}(t_2) 间的距离即可确定两条射线相交的情况。
    • 当其两点重合时便代表相交。
    • 由于浮点数的精度问题,实际中往往需要用一个偏差值。
       
  • 上面的讨论假设没有限定 t1t_1t2t_2 的取值范围,如果射线的长度有限(或者只沿一个方向延伸),在计算出 t1t_1t2t_2 后还应作适当的边界检测。