射线

已知射线方程为 P ( t ) = P ˉ + t ∗ D ˉ P(t)=\bar{P}+t*\bar{D} P(t)=Pˉ+tDˉ,其中 P ˉ \bar{P} Pˉ为射线的起点 ( x 0 , y 0 , z 0 ) (x_0,y_0,z_0) (x0,y0,z0) D ˉ \bar{D} Dˉ为射线的方向向量,其模长为 1 1 1,只要知道距离 t t t,我们就可以计算出对应点的坐标。

球体求交

不妨设球体的方程为 ( X ˉ − C ˉ ) 2 = R 2 (\bar{X}-\bar{C})^2=R^2 (XˉCˉ)2=R2,其中 X ˉ \bar{X} Xˉ为球体上任意一点的坐标, C ˉ \bar{C} Cˉ为球心, R R R为半径。射线与球体求交,首先需要将射线方程作为 X ˉ \bar{X} Xˉ带入球体方程,然后把 t t t作为未知变量,化简即可得到下式: D 2 t 2 + 2 ( P ˉ ∗ D ˉ − C ˉ ∗ D ˉ ) t − 2 C ˉ ∗ P ˉ + P 2 + C 2 − R 2 = 0 D^2t^2+2(\bar{P}*\bar{D}-\bar{C}*\bar{D})t-2\bar{C}*\bar{P}+P^2+C^2-R^2=0 D2t2+2(PˉDˉCˉDˉ)t2CˉPˉ+P2+C2R2=0
显然我们可以把上式当作一个关于 t t t的一元二次方程: a t 2 + b t + c = 0 at^2+bt+c=0 at2+bt+c=0,判断是否存在交点即判断该一元二次方程的判别式: Δ = b 2 − 4 ∗ a ∗ c Δ=b^2-4*a*c Δ=b24ac是否大于等于 0 0 0,如果是的话说明方程有解,通过求根公式得到两个解: t 1 = − b 2 − 4 a c / ( 2 ∣ a ∣ ) − b / ( 2 a ) t_1=-\sqrt{b^2-4ac}/(2|a|)-b/(2a) t1=b24ac /(2a)b/(2a) t 2 = b 2 − 4 a c / ( 2 ∣ a ∣ ) − b / ( 2 a ) t_2=\sqrt{b^2-4ac}/(2|a|)-b/(2a) t2=b24ac /(2a)b/(2a)排除掉无效解(<0的解)后,取最小的那个解即可。

三角求交

射线与球体/三角面片求交
这个过程可以分成两步, ( 1 ) (1) (1)计算射线和平面 A B C ABC ABC的交点 Q Q Q ( 2 ) (2) (2)判断 Q Q Q是否在三角形 A B C ABC ABC内部。

计算交点Q

我们知道一个平面方程可以写成 a x + b y + c z = d ax+by+cz=d ax+by+cz=d的形式,且这个平面的法向量为 ( a , b , c ) (a,b,c) (a,b,c),证明如下:在平面上任取两点 A 、 B A、B AB,显然有 a x 1 + b y 1 + c z 1 = d , a x 2 + b y 2 + c z 2 = d ax_1+by_1+cz_1=d,ax_2+by_2+cz_2=d ax1+by1+cz1=d,ax2+by2+cz2=d,两式相减可得: a ( x 2 − x 1 ) + b ( y 2 − y 1 ) + c ( z 2 − z 1 ) = 0 a(x_2-x_1)+b(y_2-y_1)+c(z_2-z_1)=0 a(x2x1)+b(y2y1)+c(z2z1)=0,假设 n = ( a , b , c ) n=(a,b,c) n=(a,b,c),上市其实就等于 n ˉ ∗ A B ˉ = 0 \bar{n}*\bar{AB}=0 nˉABˉ=0,所以 n ˉ \bar{n} nˉ就是平面的法向量。那么这个平面方程可以写成: n ˉ ∗ x ˉ = d \bar{n}*\bar{x}=d nˉxˉ=d,将射线方程带入化简可得:
射线与球体/三角面片求交
所以我们需要先判断 n ˉ ∗ d ˉ \bar{n}*\bar{d} nˉdˉ是否为 0 0 0,如果为 0 0 0说明射线和平面平行,否则可以根据上式计算出 t t t从而计算出 Q Q Q的坐标。

关于平面的一些问题

射线与球体/三角面片求交
射线与球体/三角面片求交
上面的推导来源于平面方程 a x + b y + c z = d ax+by+cz=d ax+by+cz=d,然而现在我们仅仅知道三角形三个顶点 A 、 B 、 C A、B、C ABC的坐标,如何计算 n ˉ \bar{n} nˉ d d d就成为一个问题。计算法向量比较简单,利用叉积即可完成: n ˉ = A B ˉ × A C ˉ \bar{n}=\bar{AB}×\bar{AC} nˉ=ABˉ×ACˉ(记得归一化),那么由之前的推导可知 d = n ˉ ∗ x ˉ d=\bar{n}*\bar{x} d=nˉxˉ x ˉ \bar{x} xˉ为平面内任意点的坐标,我们可以选取顶点 A A A d = n ˉ ∗ A d=\bar{n}*A d=nˉA(上面这个英文 p d f pdf pdf写得这么多,只是在探讨叉积的方向问题)。

判断Q是否在三角形内部

射线与球体/三角面片求交
射线与球体/三角面片求交
简单来说,就是通过叉乘的方向来判断。可以看上面的图示,感觉比较清晰。

计算重心坐标

得到 Q Q Q的坐标之后,我们可以对法线进行插值。
射线与球体/三角面片求交
射线与球体/三角面片求交
根据三角形面积的比值计算出 α 、 β 、 γ α、β、γ αβγ,然后根据三个顶点的法向量进行插值, N Q N_Q NQ可以用于后续的着色、反射和折射计算。

相关文章: