HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2016
0608
kn多粒子の衝突のアルゴリズム3解決


kn

リンク

2016/6/8(Wed) 22:38:34|NO.75791

HSPを使わせていただいています。
授業で多粒子の衝突(反発係数が1)を説明したいと考えていますが、
壁との衝突まで出来ましたが、粒子同士の衝突が出来ません。
アルゴリズム等をご教示お願いいたします。
(obaqでやってみましたが、反発係数1が出来ませんでしたので諦めました。)
よろしくお願いいたします。

#include "hgimg3.as"
//
wx=1366:wy=768
bgscr 0,wx,wy,0,0,0
hgini
//
s=16 //円テクスチャの作成
buffer 1,s,s,0:color:boxf
color 255,255,255
circle 0,0,s,s,0
settex:tex1=stat
//
ddim px,100 //座標用
ddim py,100
ddim pvx,100 //初速度用
ddim pvy,100
//
wallx1=0
wallx2=wx
wally1=0
wally2=wy
//
v1=1.0
//

////////初期座標////
num=0
wire=0
for i,0,10 //横の並び
for j,0,10 //縦の並び
ddx=100.0
ddy=100.0
x0=50.0
y0=50.0
x=x0+ddx*i
if wire=0:y=y0+ddy*j
if wire=1:y=y0+ddy*(1.0*j+0.5)

px.num=x //初期座標
py.num=y

th=0.02*rnd(315)
pvx.num=1.0*v1*sin(th) //初速度
pvy.num=1.0*v1*cos(th)
num++
next
if wire=0:wire=1:goto *a100
if wire=1:wire=0:goto *a100
*a100
next
sum=num //粒子の総数

//////// main ////////////////////////////////////////////////
*main
hgdraw

for j,0,sum //座標を計算
px.j=px.j+pvx.j
py.j=py.j+pvy.j
next
//球の衝突の処理
//????????


for j,0,sum
//左右壁の衝突の処理
if px.j<=wallx1 or px.j>=wallx2 :pvx.j=-pvx.j
//上下壁の衝突の処理
if py.j<=wally1 or py.j>=wally2 :pvy.j=-pvy.j
next

//描画
for j,0,sum
gmode 2,s,s:pos px.j,py.j
hgrotate tex1,0,0,0,s,s
next
stick k,0
if k&128 : goto *owari ; [ESC]で終了

hgsync 2
goto *main
////////////////////////////////
*owari
end



この記事に返信する


motchy

リンク

2016/6/8(Wed) 23:37:44|NO.75792

お疲れ様です。こんなのでよかったらどうぞ。


#define s 16 //粒子直径 #const double r 0.5*s //粒子半径 r2 = r*r //半径^2 #define T_mainLoop 2 //メインループ周期[ms] #define cReb 1.0 //反発係数 #include "hgimg3.as" // wx=1366:wy=768 bgscr 0,wx,wy,0,0,0 hgini // //円テクスチャの作成 buffer 1,s,s,0:color:boxf color 255,255,255 circle 0,0,s,s,0 settex:tex1=stat // ddim px,100 //座標用 ddim py,100 ddim pvx,100 //(初)速度用 ddim pvy,100 // wallx1=0 wallx2=wx wally1=0 wally2=wy // v1=1.0 // ////////初期座標//// num=0 wire=0 for i,0,10 //横の並び for j,0,10 //縦の並び ddx=100.0 ddy=100.0 x0=50.0 y0=50.0 x=x0+ddx*i if wire=0:y=y0+ddy*j if wire=1:y=y0+ddy*(1.0*j+0.5) px.num=x //初期座標 py.num=y th=0.02*rnd(315) pvx.num=1.0*v1*sin(th) //初速度 pvy.num=1.0*v1*cos(th) num++ next if wire=0:wire=1:goto *a100 if wire=1:wire=0:goto *a100 *a100 next sum=num //粒子の総数 //////// main //////////////////////////////////////////////// *main hgdraw for j,0,sum //座標を計算 px.j=px.j+pvx.j py.j=py.j+pvy.j next /* 衝突処理 */ repeat sum i=cnt repeat sum-i-1 j=i+cnt+1 /* 衝突判定 */ dist = sqrt(powf(px(i)-px(j),2)+powf(py(i)-py(j),2)) if (dist <= s) { //衝突 dup xi,px(i) : dup yi,py(i) dup vxi,pvx(i) : dup vyi,pvy(i) dup xj,px(j) : dup yj,py(j) dup vxj,pvx(j) : dup vyj,pvy(j) _X = xi-xj : _Y = yi-yj _Vx = vxi-vxj : _Vy = vyi-vyj if (absf(_Vx*_Vx+_Vy*_Vy) == 0.0) : continue //あまりにも小さい場合は断念する t1 = (_X*_Vx+_Y*_Vy + sqrt(powf(_X*_Vx+_Y*_Vy,2)-(_Vx*_Vx+_Vy*_Vy)*(_X*_X+_Y*_Y-4.0*r2)))/(_Vx*_Vx+_Vy*_Vy) //今からt1(秒? あなたの世界設定による。)前に衝突した /* 両者の速度を衝突面の法線,接線成分に分解する */ inx = -_X/dist : iny = -_Y/dist //法線方向単位ベクトル (i番ボール基準) itx = -iny : ity = inx //接線方向〃 vi_n = inx*vxi + iny*vyi //i番ボール速度の法線成分 vi_t = itx*vxi + ity*vyi //〃接線成分 vj_n = inx*vxj + iny*vyj //j番ボール速度の法線成分 vj_t = itx*vxj + ity*vyj //〃接線成分 /* 両者を接触位置に戻す */ xi -= vxi*t1 : yi -= vyi*t1 xj -= vxj*t1 : yj -= vyj*t1 /* 速度を更新 */ vi_n_new = 0.5*((1.0-cReb)*vi_n + (1.0+cReb)*vj_n) vj_n_new = 0.5*((1.0-cReb)*vj_n + (1.0+cReb)*vi_n) vxi = vi_n_new*inx + vi_t*itx : vyi = vi_n_new*iny + vi_t*ity vxj = vj_n_new*inx + vj_t*itx : vyj = vj_n_new*iny + vj_t*ity /* 移動 */ xi += vxi*t1 : yi += vyi*t1 xj += vxj*t1 : yj += vyj*t1 } loop loop for j,0,sum //左右壁の衝突の処理 if px.j<=wallx1 or px.j>=wallx2 :pvx.j=-pvx.j //上下壁の衝突の処理 if py.j<=wally1 or py.j>=wally2 :pvy.j=-pvy.j next //描画 for j,0,sum gmode 2,s,s:pos px.j,py.j hgrotate tex1,0,0,0,s,s next stick k,0 if k&128 : goto *owari ; [ESC]で終了 hgsync T_mainLoop goto *main //////////////////////////////// *owari end



kn

リンク

2016/6/9(Thu) 15:46:54|NO.75794

教えていただき、誠にありがとうございました。
お陰様で、理科の授業「物質の三態」の構成粒子の熱運動のイメージを
上手く見せる事が出来ました。感謝いたします。

#include "hgimg3.as"
//#epack "ball-sb80.bmp"
#define s 32 //16 //粒子直径
#const double r 0.5*s //粒子半径
r2 = r*r //半径^2
#define cReb 1.0 //反発係数
//
wx=1366:wy=768
bgscr 0,wx,wy,0,0,0
hgini
//
ddim px,100 //座標用
ddim py,100
ddim pvx,100 //(初)速度用
ddim pvy,100
//
wallx1=0 //壁
wallx2=wx
wally1=0
wally2=wy
v1=1.0  //速度用
//球の読み込み
//円テクスチャの作成
texs=s
buffer 1,texs,texs,0:boxf
color 255,255,255
circle 0,0,texs,texs,1
settex:tex1=stat
//texload "ball-sb80.bmp":texs=80:tex1=stat //実際は画像を使っています。

//メニュー用
color 255,255,255
font "MS ゴシック",16
texmake 512,16:mest1 = stat:texmes "F1:固体   F2:液体   F3:気体  ↑↓:温度",mest1,0,0
/////////////////////////////////
*reset
menu=1
rc=0.0 //背景 赤
ac=1.0 //速度の倍率
///////////////////粒子の初期座標///////////////////////////////
num=0
wire=0
for i,0,16//13 //横の並び
for j,0,9//7  //縦の並び
ddx=80.0
x0=80.0
y0=50.0
x=x0+ddx*i
if wire=0:y=y0+ddx*j
if wire=1:y=y0+ddx*(1.0*j+0.5)
px.num=x //初期座標
py.num=y
num++
next
if wire=0:wire=1:goto *a100
if wire=1:wire=0:goto *a100
*a100
next
sum=num //粒子の総数
///////////////// main ////////////////////////////////////////////////
*main
hgdraw
color 0,255,255
//hgrect 200,100,0,200,100
hgline 0+4,0+4,wx-3,0+4
hgline 0+4,wy-4,wx-3,wy-4
hgline 3,4,3,wy-4
hgline wx-3,4,wx-3,wy-4
/////////////背景の色
gc=0//green
bc=0//blue
if rc<0:rc=0.0
if rc>255:rc=255.0

col="$" +strf("%02x",int(rc)) + strf("%02x",gc) + strf("%02x",bc)
clscolor $+col
//文字テクスチャの描画
color 255,0,0:gmode 2,512,16  
pos 300,16:hgrotate mest1

////////////////////////固体の振動
if menu=1 {
for j,0,sum
th=0.02*rnd(315)
pvx.j=1.0*ac*v1*sin(th)
pvy.j=1.0*ac*v1*cos(th)
x=px.j+pvx.j
y=py.j+pvy.j
gmode 2,texs,texs:pos x,y :hgrotate tex1,0,0,0,s,s
next
}
////////////////////////液体
if menu=2 {
for j,0,sum
th=0.02*rnd(315)
pvx.j=0.3*ac*v1*sin(th)
pvy.j=0.3*ac*v1*cos(th)
px.j=px.j+pvx.j
py.j=py.j+pvy.j
gmode 2,texs,texs:pos px.j,py.j :hgrotate tex1,0,0,0,s,s
next
}
//////////////////////////気体
if menu=3 {
for j,0,sum //座標
px.j=px.j+5.0*ac*pvx.j
py.j=py.j+5.0*ac*pvy.j

//左右壁の衝突の処理
if px.j<=wallx1+s :px.j=1.0*wallx1+s :pvx.j=-pvx.j
if px.j>=wallx2-s :px.j=1.0*wallx2-s :pvx.j=-pvx.j
//上下壁の衝突の処理
if py.j<=wally1+s :py.j=1.0*wally1+s :pvy.j=-pvy.j
if py.j>=wally2-s :py.j=1.0*wally2-s :pvy.j=-pvy.j
next

/* 衝突処理 */
repeat sum
i=cnt
repeat sum-i-1
j=i+cnt+1
/* 衝突判定 */
dist = sqrt(powf(px(i)-px(j),2)+powf(py(i)-py(j),2))
if (dist <= s) { //衝突
dup xi,px(i) : dup yi,py(i)
dup vxi,pvx(i) : dup vyi,pvy(i)
dup xj,px(j) : dup yj,py(j)
dup vxj,pvx(j) : dup vyj,pvy(j)
_X = xi-xj : _Y = yi-yj
_Vx = vxi-vxj : _Vy = vyi-vyj
if (absf(_Vx*_Vx+_Vy*_Vy) == 0.0) : continue //あまりにも小さい場合は断念する
t1 = (_X*_Vx+_Y*_Vy + sqrt(powf(_X*_Vx+_Y*_Vy,2)-(_Vx*_Vx+_Vy*_Vy)*(_X*_X+_Y*_Y-4.0*r2)))/(_Vx*_Vx+_Vy*_Vy) //今からt1(秒? あなたの世界設定による。)前に衝突した
/* 両者の速度を衝突面の法線,接線成分に分解する */
inx = -_X/dist : iny = -_Y/dist //法線方向単位ベクトル (i番ボール基準)
itx = -iny : ity = inx //接線方向〃
vi_n = inx*vxi + iny*vyi //i番ボール速度の法線成分
vi_t = itx*vxi + ity*vyi //〃接線成分
vj_n = inx*vxj + iny*vyj //j番ボール速度の法線成分
vj_t = itx*vxj + ity*vyj //〃接線成分
/* 両者を接触位置に戻す */
xi -= vxi*t1 : yi -= vyi*t1
xj -= vxj*t1 : yj -= vyj*t1
/* 速度を更新 */
vi_n_new = 0.5*((1.0-cReb)*vi_n + (1.0+cReb)*vj_n)
vj_n_new = 0.5*((1.0-cReb)*vj_n + (1.0+cReb)*vi_n)
vxi = vi_n_new*inx + vi_t*itx : vyi = vi_n_new*iny + vi_t*ity
vxj = vj_n_new*inx + vj_t*itx : vyj = vj_n_new*iny + vj_t*ity
/* 移動 */
xi += vxi*t1 : yi += vyi*t1
xj += vxj*t1 : yj += vyj*t1
}
loop
loop

//描画
for j,0,sum
gmode 2,texs,texs:pos px.j,py.j
hgrotate tex1,0,0,0,s,s
next

}
/////
hgsync 2
//////////////////////////////////////////////////////////////////////
stick k,0
if k&128 : goto *owari ; [ESC]で終了

if k&16 {
repeat
stick k,0
if k&128 : goto *owari ; [ESC]で終了
if k&16 : break ; スペースでぬける
loop
}
// ↑
drc=0.4
getkey k,38:if k&1{
if menu=1:ac=1.0*ac*1.008:rc=rc+drc:goto *main
if menu=2:ac=1.0*ac*1.009:rc=rc+drc:goto *main
if menu=3:ac=1.0*ac*1.02:rc=rc+drc:goto *main
}
// ↓
getkey k,40:if k&1{
if menu=1:ac=1.0*ac/1.008:rc=rc-drc:goto *main
if menu=2:ac=1.0*ac/1.009:rc=rc-drc:goto *main
if menu=3:ac=1.0*ac/1.02:rc=rc-drc:goto *main
}
//
getkey k,112:if k&1:menu=1:goto *reset;F1
getkey k,113:if k&1:menu=2:goto *main;F2
getkey k,114:if k&1:menu=3:goto *main ;F3

/////////////////////////////////////////////////////
goto *main
*owari
end



kn

リンク

2016/6/9(Thu) 16:12:48|NO.75795

解決済みのチェックを忘れていました。



ONION software Copyright 1997-2023(c) All rights reserved.