レイと球の交差点

最終更新日18 Feb 2017 08:03

レイの定義

(1)
\begin{align} R(t)=P + td\newline t \geq 0 \end{align}

P….レイの原点
d…は正規化した方向ベクトルで長さ1$\|d\|=1$
球の定義は、
C….球の中心
r……球の半径
球の表面に存在するレイとの交差点は以下のように表現できます。

(2)
\begin{align} (P+td-C)\cdot (P+td-C)=r^2 \end{align}

tが何か分かれば、交差点がわかります。
なので、この式をtの2次方程式になるように展開しましょう。

(3)
\begin{align} t^2d\cdot d+2(P-C)td+(P-C)^2=r^2\newline t^2d\cdot d+2(P-C)td+(P-C)^2-r^2=0 \end{align}

dは正規化ベクトルなのでd・d=1なので消せます

(4)
\begin{equation} t^2+2(P-C)td+(P-C)^2-r^2=0 \end{equation}

tに関する2次方程式になりました。
2次方程式の解にあてはめると2次方程式の解はここ

(5)
\begin{align} t=\frac{-2(P-C)d\pm \sqrt{(2(P-C)d)^2-4((P-C)^2-r^2)}}{2}\newline t=-(P-C)d\pm \sqrt{((P-C)d)^2-((P-C)^2-r^2)} \end{align}

またd2が出てきましたが、これも結果が1になるので消せます

(6)
\begin{align} t=-(P-C)d\pm \sqrt{(P-C)^2-((P-C)^2-r^2)} \end{align}

さらにルートの中を整理すると

(7)
\begin{align} t=-(P-C)d\pm \sqrt{(P-C)^2-(P-C)^2+r^2}\\ t=-(P-C)d\pm \sqrt{r^2}\\ t=-(P-C)d\pm r \end{align}

となるけど、こういう風にしてしまうとうまくいかないのでやめておく。

ソースコード

//hit ray sphere test
bool hit(vec3 orig,vec3 dir,vec3 center,float r,out vec3 intersect){
    vec3 oc = orig - center;
    float b = dot(oc,dir);
    float c = dot(oc,oc) - r * r;
    if(c>0.0f && b > 0.0f) return false;
    float discriminant = b*b -c;
    if(discriminant < 0.0) return false;
    float t= -b-sqrt(discriminant);
    if(t<0.0) return false;
    intersect = orig + t*dir;
    return true;  
}

デモ

レイと球の交点を求めてフラグメントシェーダだけで球を描画しました。


by ShaderToy


ray-intersection


files

サポートサイト Wikidot.com ray-intersection