解説

重なっていない場合

もし A,BA, B が初期状態で衝突しておらず、後で衝突するときを考えます。

AA のある辺について、始点の位置ベクトルを a\boldsymbol{a} 、そこから終点までのベクトルを u\boldsymbol{u} とします。 BB のある頂点の位置ベクトルを b\boldsymbol{b}BB が移動する速度のベクトルを v\boldsymbol{v} とします。

AA の辺と BB の頂点が衝突すると考えたとき、衝突する点は変数 t,st, s を用いて a+su=b+tv\boldsymbol{a} + s \boldsymbol{u} = \boldsymbol{b} + t \boldsymbol{v} と表せます。 この式は二元一次連立方程式であるため、行列計算によって s,ts, t を求めることが可能です。

このとき、 0s10 \le s \le 1 かつ t0t \ge 0 なら実際に時間 tt で衝突していると考えられます。

これを AA のすべての辺と BB のすべての頂点について行います。

次に、同じことを、 AA が速度 v-\boldsymbol{v}BB に向かっていると考えて、 A,BA, B を逆にして行います。

これによって衝突する最短の時間がわかります。

重なっている場合

上で述べた方法は、 A,BA, B が初期状態で重なっている場合はうまくいきません。

例えば次のような場合を考えてみましょう。

corner

この例では頂点と辺がくっついているわけではないため、上で述べた解き方では正しい衝突までの時間が出ません。 そこで、三角形が重なっているか判定し、重なっていれば 0 を出力します。

2 つの三角形が重なっているとき、片方の辺ともう片方の辺が重なっています。 互いの辺について重なっていないか 323^2 通り試すことで判定することができます。