Ray Tracing in WebGL » Cone

Rendering of a cone

Equation of a cone

まず円柱を表す式について確認する.下図において,p1が3次元座標の原点,p2がz軸上にある場合,無限に長い円柱は以下の式で表される.

$$ \begin{equation} X^2 + Y^2 = (aZ)^2, ~~ \mathrm{where} ~~ a = \frac{\mathrm{radius1}-\mathrm{radius2}}{|\boldsymbol{p}_2-\boldsymbol{p}_1|} \tag{1} \end{equation} $$

円錐のローカルな基底は以下のように求められる.

$$ \begin{equation} \boldsymbol{R}_\mathrm{X} = \frac{\boldsymbol{p}_3-\boldsymbol{p}_1}{|\boldsymbol{p}_3-\boldsymbol{p}_1|}, ~~ \boldsymbol{R}_\mathrm{Z} = \frac{\boldsymbol{p}_2-\boldsymbol{p}_1}{|\boldsymbol{p}_2-\boldsymbol{p}_1|}, ~~ \boldsymbol{R}_\mathrm{Y} = \boldsymbol{R}_\mathrm{Z} \times \boldsymbol{R}_\mathrm{X} \tag{2} \end{equation} $$

円錐のローカル座標の原点は円錐の頂点に取りたいので,この位置をグローバル座標で確認しておこう.

$$ \begin{equation} \boldsymbol{p}_0 = \frac{\mathrm{radius1}}{\mathrm{radius1}-\mathrm{radius2}} (\boldsymbol{p}_2-\boldsymbol{p}_1) \tag{3} \end{equation} $$

Intersections of a ray and a cone

一般の位置・方向の円錐を式で表すと複雑になるので,(1)で表された円錐と直線の交点を求めよう.

$$ \begin{equation} \left[ \begin{array}{c} x \\ y \\ z \end{array} \right] = \left[ \begin{array}{c} x_\mathrm{o} \\ y_\mathrm{o} \\ z_\mathrm{o} \end{array} \right] + t \left[ \begin{array}{c} u_l \\ v_l \\ w_l \end{array} \right] \tag{4} \end{equation} $$

直線(3)をローカル座標に変換すると,(4)の形に書き換えられる.

$$ \begin{gather} \left[ \begin{array}{c} X \\ Y \\ Z \end{array} \right] = \left[ \begin{array}{c} X_\mathrm{o} \\ Y_\mathrm{o} \\ Z_\mathrm{o} \end{array} \right] + t \left[ \begin{array}{c} U_l \\ V_l \\ W_l \end{array} \right], ~~ \mathrm{where}~ \left[ \begin{array}{c} X_\mathrm{o} \\ Y_\mathrm{o} \\ Z_\mathrm{o} \end{array} \right] = \left[ \begin{array}{ccc} \boldsymbol{R}_\mathrm{X} & \boldsymbol{R}_\mathrm{Y} & \boldsymbol{R}_\mathrm{Z} \end{array} \right]^\mathrm{T} \left\{ \left[ \begin{array}{c} x_\mathrm{o} \\ y_\mathrm{o} \\ z_\mathrm{o} \end{array} \right] - \boldsymbol{p}_0 \right\} ~\mathrm{and}~ \left[ \begin{array}{c} U_l \\ V_l \\ W_l \end{array} \right] = \left[ \begin{array}{ccc} \boldsymbol{R}_\mathrm{X} & \boldsymbol{R}_\mathrm{Y} & \boldsymbol{R}_\mathrm{Z} \end{array} \right]^\mathrm{T} \left[ \begin{array}{c} u_l \\ v_l \\ w_l \end{array} \right] \tag{5} \end{gather} $$

これを(1)に代入し,tについての2次方程式を解くと,円柱と直線の交点がローカル座標で求められる.

$$ \begin{gather} (X_\mathrm{o} + tU_l)^2 + (Y_\mathrm{o} + tV_l)^2 = a^2(Z_\mathrm{o} + tW_l)^2 \tag{6} \\ (U_l^2 + V_l^2 - a^2 W_l^2) t^2 + 2(X_\mathrm{o}U_l + Y_\mathrm{o}V_l - a^2 Z_\mathrm{o}W_l)t + X_\mathrm{o}^2 + Y_\mathrm{o}^2 - a^2 Z_\mathrm{o}^2 = 0 \tag{7} \end{gather} $$

交点の数は判別式を用いて確認できる.

$$ \begin{equation} D = (X_\mathrm{o}U_l + Y_\mathrm{o}V_l - a^2 Z_\mathrm{o}W_l)^2 - (U_l^2 + V_l^2 - a^2 W_l^2)(X_\mathrm{o}^2 + Y_\mathrm{o}^2 - a^2 Z_\mathrm{o}^2) \tag{8} \end{equation} $$

交点が存在する場合,対応するtは以下のように求められる.

$$ \begin{equation} t_\pm = \frac{-(X_\mathrm{o}U_l + Y_\mathrm{o}V_l - a^2 Z_\mathrm{o}W_l) \pm \sqrt{D}}{U_l^2 + V_l^2 - a^2 W_l^2} \tag{9} \end{equation} $$

これより交点のローカル座標は以下のように表される.

$$ \begin{equation} \left[ \begin{array}{c} X_\pm \\ Y_\pm \\ Z_\pm \end{array} \right] = \left[ \begin{array}{c} X_\mathrm{o} \\ Y_\mathrm{o} \\ Z_\mathrm{o} \end{array} \right] + t_\pm \left[ \begin{array}{c} U_l \\ V_l \\ W_l \end{array} \right] \tag{10} \end{equation} $$

得られた交点が,円錐の特定の一部に含まれるかは,以下の条件を確認すればよい.

$$ \begin{equation} -|\boldsymbol{p}_2 - \boldsymbol{p}_1| \le Z \le 0 \tag{11} \end{equation} $$ $$ \begin{equation} \mathrm{start\_angle} \le \theta \le \mathrm{end\_angle}, ~~ \mathrm{where}~~ \theta = \mathrm{atan2}(Y, X) \tag{12} \end{equation} $$