オブジェクトが衝突したときに、以下で説明するように1回実行します。
緑の長方形を「a」、もう一方を「b」と呼びましょう。
1.1。
まず、長方形の「回転質量」、慣性質量が必要です。
ai = 4/3 *幅*高さ*(幅^ 2+高さ^2)*a。密度
2.2。
次に、長方形の重心(すべての角の平均位置)から接触位置(長方形が衝突する場所)を指すベクトルが必要です。これを「r」と呼びます。
3.3。
次に、衝突法線を見つける必要があります。この法線は、bからaに適用されるインパルスの方向です。法線は、長さが1単位のベクトルです。あなたの例では、法線はおそらく上向きになります。法線ベクトルを「n」と呼びましょう。
4.4。
ここで、上の接触点の速度が必要になります。aが回転していない場合、式は次のようになります。
vp = a.vel
aが回転している場合、式は次のようになります。
vp = a.vel + cross(a.r_vel、r)
a.r_velはラジアンで与えられるaの回転速度であり、正の方向は反時計回りです。
cross()は外積を意味し、関数は次のとおりです。
cross(v、i)= [-i * vy、i * vx]
展開された式は次のようになります。
vp = av + [-r * a.r_vel.y、r * a.r_vel.x]
5.5。
次に、オブジェクトが互いに向かって移動しているかどうかを計算する必要があります。vpをnに投影します。
vp_p = dot(vp、n)
ドット(v1、v2)= v1.x * v2.x + v1.y * v2.y
vp_pはスカラー(ベクトルではなく値)です。
vp_pが負の場合、オブジェクトは互いに向かって移動し、0より大きい場合、オブジェクトは離れて移動します。
6.6。
ここで、aがbに移動するのを防ぐために、インパルスを計算する必要があります。インパルスは次のとおりです。
j = -vp_p /(1 / a.mass + cross(r、n)^ 2 / ai)
2つのベクトル間の外積は次のとおりです。
cross(v1、v2)= v1.x * v2.y-v1.y * v2.x
スカラーを返します。
インパルスに法線を掛けて、インパルスベクトルを取得します。
jn = j * n
7。
次に、インパルスを以下に適用する必要があります。
a.new_vel = a.old_vel + jn / a.mass;
a.new_r_vel = a.old_r_vel + cross(r、jn)/ ai;
衝突を完全に弾力性のあるものにしたい場合は、力積に2を掛ける必要があります。この乗数を「e」と呼びます。eは1から2の間である必要があります。1はエネルギーが節約されないことを意味し、2はすべてのエネルギーが節約されることを意味します。
コード例:
var vp = a.vel + cross(a.r_vel, r);
var vp_p = dot(vp,n); // negative val = moving towards each other
if (vp_p >= 0) { // do they move apart?
return false;
}
// normal impulse
var j = - e * vp_p / (
1/a.mass + cross(r,n)^2 / a.i
);
var jn = j * n;
//
a.vel = a.vel + jn / a.mass;
a.r_vel = a.r_vel + cross(r,jn) / a.i;
bが静的でない場合、アルゴリズムはわずかに異なります。
ar=aの重心から接触位置を指すベクトル
var vp = a.vel + cross(a.r_vel, a.r) - b.vel - cross(b.r_vel, b.r);
var vp_p = dot(vp,n); // negative val = moving towards each other
if (vp_p >= 0) { // do they move apart?
return false;
}
// normal impulse
var j = - e * vp_p / (
1/a.mass + cross(a.r,n)^2 / a.i +
1/b.mass + cross(b.r,n)^2 / b.i
);
var jn = j * n;
//
a.vel = a.vel + jp / a.mass;
a.r_vel = a.r_vel + cross(a.r,jn) / a.i;
b.vel = b.vel - jp / b.mass;
b.r_vel = b.r_vel - cross(b.r,jn) / b.i;
数式のしくみ/出典:
http://www.myphysicslab.com/collision.html#resting_contact