ソフトウェア開発したい日記

「面白い!」と思った頭の体操や、数学の問題を載せていきます
その他ロードバイクででかけた先の写真や、ソフト開発のメモ等

ボールと壁の当たり判定

2010年04月29日 18時33分33秒 | ソフト開発日記
ボールと壁の当たり判定についてのメモ。
今まで適当にやってたけど、接触判定は
壁の法線ベクトルを利用するのがいいらしい。

まず、ボールが等速運動する場合、
p(x, y)を現在の座標
v(vx, vy)を現在の速度
p'(x', y')を次フレームの座標
v'(vx', vy')を次フレームの速度
とすると、

p' = p + v
v' = v

と表される。
ここで加速度a(ax, yx)がある場合は、

v' = v + a

となる。
どちらも1フレームの間では等速運動しているように考えている(離散化)。
こう考えることで、計算が楽になるとのこと。

次いで、壁との接触判定について。
ボールと壁が当たっているか否かは、下式を満たすか否かで判定できる。

(ボールの半径)>(ボールの中心座標と壁との距離)

この式を満たすとき、ボールは壁にめり込んだ状態
すなわち、壁と接触している。
ここで壁の座標を、次のように正規化された方程式で表すことにする。

ax + by + d = 0 (a^2 + b^2 = 1)

このとき、この壁と円の中心座標p(p_x, p_y)との距離Lは次のとおり。

L = ap_x + bp_y + d

すなわち、ap_x + bp_y + d = r となっているとき、ボールと壁は接触している。
今からtフレーム後の位置p'は

p'(p'_x, p'_y) = p(p_x, p_y) + v(v_x, v_y)t
        = (p_x + v_x * t, p_y + v_y * t)

であり、tフレーム後に接触するならば、

ap'_x + bp'_y + d = r

これらよりtを求めると

t = - (ap_x + bp_y + d - r) / (av_x + bv_y)

となる。
接触は t <1 のときに行えばよい。 しかしながら、大量のボールに関してすべて毎度毎度この判定をしていたら
かなりもっさりとしたプログラムになってしまう。

そこで使う方法の1つが、壁の法線ベクトルと。
まず壁の法線ベクトルと、ボールの速度ベクトルの内積を計算する。
すなわち、av_x + bv_y を求める。

この値が0より大きいとき、ボールは壁の法線と同方向に
0より小さいとき、ボールは壁の法線と逆方向に(つまり壁方向に)移動している。
つまり、壁の接触判定は av_x + bv_y <0 のときだけおこなえばよいと。 また、av_x + bv_y = 0 のときは壁に平行に進んでいることになり
このときも接触判定をおこなう必要はなし。

次はボール同士の衝突とかについて・・。