N88-BASICでゲーム (1回目)
2021/8/16(月)
N88-BASICでゲーム (1回目)
by ULproject
球同士の衝突と跳返り
大文字ベクトル、小文字スカラー
文字の後の、'は衝突後、数字は球番号
球同士の反発係数、衝突面に水平,垂直u,e
球の中心位置P,半径r,質量m,速度V
衝突面の球1方向の法線N = (P1-P2)/|P1-P2|
球同士の衝突は、
|P1-P2| ≦ r1+r2 なので
√{(P1-P2)・(P1-P2)} ≦ r1+r2
(P1-P2)・(P1-P2) ≦ (r1+r2)(r1+r2)
で判断できます。
ここで、ベクトルの計算ですが、
P(i) (i=0,1,2) をPのx,y,z成分と
すると、
P = P1 - P2は、
P(i) = P1(i) - P2(i) (i=0,1,2)
P・Pは
ΣP(i)P(i) (i=0,1,2)
となります
BASICでは、
P(0) = P1(0) - P2(0)
P(1) = P1(1) - P2(1)
P(2) = P1(2) - P2(2)
D = P(0)*P(0)+P(1)*P(1)+P(2)*P(2)
R = R1 + R2
IF D <= R*R THEN 重なり又は接触
となります。
反発させるときは、球が接触している
間は再び反発しないようにしないと
球が離れなくなります。
次に反発についてですが、衝突面に
水平な成分は、球の回転に関係します
が、ここでは球の回転は考えずに
垂直成分と同じように反発係数で
減速させる事にします。
衝突面に垂直な成分
(v1は球1の速度、v1'は衝突後)
運動量p = mv
運動量保存則p1+p2=p1'+ p2'より
p1+p2 = m1v1'+ m2v2'
反発係数e = -(v1'- v2')/(v1 - v2)より
ev1 - ev2 = -v1'+ v2'
em2v1 - em2v2 = -m2v1'+ m2v2'
-) p1 + p2 = m1v1'+ m2v2'
--------------------------------
em2v1-p1-em2v2-p2 = -(m1+m2)v1'
v1'= {em2(v2-v1)+p1+p2}/(m1+m2)
em1v1 - em1v2 = -m1v1'+ m1v2'
+) p1 + p2 = m1v1'+ m1v2'
--------------------------------
em1v1+p1-em1v2-p2 = -(m1+m2)v2'
v2'= {em1(v1-v2)+p1+p2}/(m1+m2)
よって、
v1'= {em2(v2-v1) + m1v1 + m2v2}/(m1+m2)
v2'= {em1(v1-v2) + m1v1 + m2v2}/(m1+m2)
衝突面に水平な成分
e,viの代わりにu,uiで書きます
反発係数u = (u1'- u2')/(u1 - u2)より
上記v1'などの式を変更
(v2 - v1 ← u1 - u2、など変更)
u1'= {um2(u1-u2) + m1u1 + m2u2}/(m1+m2)
u2'= {um1(u2-u1) + m1u1 + m2u2}/(m1+m2)
これらをベクトルで書くと
(V1,V2は衝突前の速度ベクトル)
衝突面に垂直な速度成分 v1 = N・V1
衝突面に垂直な速度成分 v2 = N・V2
衝突後の垂直な速度成分
y1 = {em2(v2-v1) + m1v1 + m2v2}/(m1+m2)
y2 = {em1(v1-v2) + m1v1 + m2v2}/(m1+m2)
衝突面に水平な速度成分 u1 = |V1-v1N|
衝突面に水平な速度成分 u2 = |V2-v2N|
衝突後の水平な速度成分
x1 = {um2(u1-u2) + m1u1 + m2u2}/(m1+m2)
x2 = {um1(u2-u1) + m1u1 + m2u2}/(m1+m2)
となり
衝突後の速度ベクトルは
V1'= (V1-v1N)x1/u1 + y1N
V2'= (V2-v2N)x2/u2 + y2N
となります
BASICでは、
N(0) = P1(0) - P2(0)
N(1) = P1(1) - P2(1)
N(2) = P1(2) - P2(2)
D = N(0)*N(0)+N(1)*N(1)+N(2)*N(2)
D = SQR(D)
N(0) = N(0) / D
N(1) = N(1) / D
N(2) = N(2) / D
V1 = N(0)*V1(0)+N(1)*V1(1)+N(2)*V1(2)
V2 = N(0)*V2(0)+N(1)*V2(1)+N(2)*V2(2)
Y1 = (E*M2*(V2 - V1) + M1*V1 + M2*V2)/(M1+M2)
Y2 = (E*M1*(V1 - V2) + M1*V1 + M2*V2)/(M1+M2)
U1X = V1(0) - V1 * N(0)
U1Y = V1(1) - V1 * N(1)
U1Z = V1(2) - V1 * N(2)
U1 = SQR(U1X*U1X + U1Y*U1Y + U1Z*U1Z)
U2X = V2(0) - V2 * N(0)
U2Y = V2(1) - V2 * N(1)
U2Z = V2(2) - V2 * N(2)
U2 = SQR(U2X*U2X + U2Y*U2Y + U2Z*U2Z)
X1 = (U*M2*(U1 - U2) + M1*U1 + M2*U2)/(M1+M2)
X2 = (U*M1*(U2 - U1) + M1*U1 + M2*U2)/(M1+M2)
V1(0) = U1X * X1 / U1 + Y1 * N(0)
V1(1) = U1Y * X1 / U1 + Y1 * N(1)
V1(2) = U1Z * X1 / U1 + Y1 * N(2)
V2(0) = U2X * X2 / U2 + Y2 * N(0)
V2(1) = U2Y * X2 / U2 + Y2 * N(1)
V2(2) = U2Z * X2 / U2 + Y2 * N(2)
となります。
ただし、0で割らないように処理を
追加する必要があります
また、同じ計算を2度行わないように
変数に代入して使いまわすなどの工夫
をした方が良いでしょう
NL-BASICとblg~.zip(game001.bas)は
以下のリンクからダウンロードできます
Readme.txtを読んで遊んで下さい
Alt+6で高速化して下さい