さて、今回は当たり判定について話したいと思います。前編は分かりやすく、ゲームプログラミングなどでの実用性を重視してあっさり話しますが、後編はマニアックに定義や証明をしていきます。
とはいえ、自分に十分な知識と力量があるという自信もないので、間違っていたらご指摘くださいね。
「たかが点どうしの当たり判定で前後編とはなんのこっちゃ」と思った方も居るかもしれませんが、1つの投稿が長くなりすぎると読む気がしないなぁ、と思って分けることにしました。
この投稿もだいぶ長いですが、多めに見てやってください(^^;)
ゲーム制作をしている人は知っている人も多いと思いますが、「当たり判定」とは主に2つの図形が当たっているかどうかを調べることです。
人間からすれば図を描いて確かめれば済むのですが、コンピューターに図を見せても分かりませんから、図形をデータにして計算によって当たっているかどうかを判定する必要があります。
今回は「平面上の点と点の当たり判定」です。今後も準備ができ次第いろんな当たり判定を紹介する予定です。
点と点の当たり判定
平面上の「点」は、2つの実数の組で表されるのがふつうです。ゲームプログラミングの際も、double型やfloat型などの実数型を2つセットで持つクラスなどが多くなるはずです。
今回は、この点が2つあるとき、どのような条件を満たせば2つの点が当たるのかを考えましょう。
といっても、「点」と「点」が当たっている状況といったら、2つの点が一致している時しか考えられないと思います。
つまり、点( x1, y1 ) と 点( x2, y2 ) は、x1 = x2 かつ y1 = y2 ならば、当たっているということになります。
これは次の図のような状態のことです。点と点が重なっているのでちょっと分かりづらいですが、当たっています。 さて、これをプログラムに書けば当たり判定ができる・・・と思ってしまいそうですが、実はこのままではうまくいきません。
ご存じの方もいるかと思いますが、double型やfloat型で計算をする時は計算誤差を免れることはできません。(C#などではdecimal型などで誤差なく計算できますが、あまり使いません)
そこで、「x1 とx2が等しい」ではなく「x1がx2に近い」と考えて判定する必要があります(yに関しても同じように考えます)。
「近い」というのは、2つの位置のあいだの距離が短いということです。x1とx2の距離は、| x1 - x2 |です。(記号|a|はaの絶対値を表します)
これが十分に小さければよいので、0に近い正の実数εを用いて、次のような条件を書けます。
| x1 - x2 | < ε かつ | y1 - y2 | < ε
これを満たす2つの点が当たっているということにすれば問題ないでしょう。
プログラムでは、例えばC#では次のように書きます。
//1つの点のx座標、y座標、もう1つの点のx座標、y座標を引数にとり、2つの点が当たっているならばtrueを返す関数(メソッド)です。
public bool Detect( float x1, float y1, float x2, float y2 )
{
float aboutZero = 1e-12f; //計算誤差の許容範囲(この値は一例です)
return Math.Abs( x1 - x2 ) < aboutZero && Math.Abs( y1 - y2 ) < aboutZero;
}
・・・しかし、本当にこれでいいのでしょうか (おい
先ほどは「2つの点が一致している時しか考えられないと思います」などと書きましたが、それはつまり「なんとなく・・・」という意味ではないでしょうか。
自分としてはここまでの考え方では納得いかず、もっときちんと考えることにしました。
という訳で、もっとしっかりと点どうしの当たり判定について考えましょう。後半へ続く。