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)は

以下のリンクからダウンロードできます

NL-BASIC(N88-BASIC互換?)ホームページ

Readme.txtを読んで遊んで下さい

 

Alt+6で高速化して下さい





このブログの人気の投稿

NEWS