調整が良くないのか長く続きません。
調整が良くないのか長く続きません。
; ; OBAQ 「ニュートンのゆりかご」 ; ; スペースキーで動かし始める。 ; 調整がうまく行っていないのか途中でバラバラになってしまいます。 ; #include "obaq.as" ;内積 #define global ctype DotProduct2D(%1,%2,%3,%4) (double(%1)*(%3) + double(%2)*(%4)) #module ; 振り子 pendulum ; num : オブジェクトID ; x,y : アンカー座標 ; distance : 距離 ; const_k : バネ定数 ; damping : 減衰 #deffunc qAttach int p_num, double p_x, double p_y, double p_distance, double p_const_k, double p_damping qgetreq@ rpr, REQ_PHYSICS_RATE ; 1フレームあたりの物理計算回数 ; オブジェクトの状態を取得 qgetpos@ p_num, hx1, hy1, hr1 qgetspeed@ p_num, vx, vy, vr qgetweight@ p_num, weiht, mt ; オブジェクトからアンカーまでの距離ベクトル dx = p_x - hx1 dy = p_y - hy1 ;cos -(dx,dy)と(vx,vy)とがなす角のcos値 dd = sqrt(dx*dx + dy*dy) vv = sqrt(vx*vx + vy*vy) if (dd=0.0) | (vv=0.0) { c = 1.0 } else { c = DotProduct2D( vx, vy, -dx, -dy ) / vv / dd } ;梁正規化 ix = dx / dd iy = dy / dd ; 減衰 v = vv * c bvx = ix * -v bvy = iy * -v cvx = 0.0 cvy = 0.0 if bvx>0 { cvx = -p_damping if (bvx - p_damping)<0 : cvx = -bvx } else { if bvx<0 { cvx = p_damping if (bvx + p_damping)>0 : cvx = -bvx } } if bvy>0 { cvy = -p_damping if (bvy - p_damping)<0 : cvy = -bvy } else { if bvy<0 { cvy = p_damping if (bvy + p_damping)>0 : cvy = -bvy } } ; バネ ;バネの伸び dl = sqrt(dx*dx + dy*dy) - p_distance ; a = x * k / m vx = ix * dl * p_const_k / weiht vy = iy * dl * p_const_k / weiht vx *= rpr ;加速度を速度に置き換え vy *= rpr qspeed@ p_num, vx + cvx, vy + cvy, 0.0 return #global qreset ; OBAQの初期化 ; オブジェクト配置 dim myball, 5 repeat 5 qaddpoly myball(cnt), 100, 60.0+10.0*cnt, 60.0, 0, 5.0,5.0, 0 qweight myball(cnt), 6.0 qdamper myball(cnt), 0.0, 0.0 qinertia myball(cnt), 1.0 qtype myball(cnt), 0x100 loop ;---------- ; 梁 ;---------- ; 硬いバネと大きな減衰で梁を表現します。 ; 梁長さ lg = 30.0 ; バネ定数 ; 値が小さいほどバネが柔らかく、よく伸びるようになります。 ;k = 0.01 k = 0.4 ; 減衰 ; 値が大きいほど振動が速く収まります。 ;cv = 0.0001 cv = 0.2 ;---------- ; 環境 ;---------- qgravity 0, 0.005 ; メインループ qgetpos mybox, px,py,pr *main redraw 0 ; 画面の更新を開始 color 0,0,0:boxf ; 画面をクリア qexec ; OBAQによるオブジェクトの更新 ; 最初に動かす stick key if key&16 : qspeed myball(0), -0.5 color 255,255,255 pos 50,50 mes "スペースキーを押してください。" ;---------- ; 振り子 ;---------- repeat 5 qAttach myball(cnt), 60.0+10.0*cnt, 30.0, lg, k, cv loop ; 紐を描画 color 255,255,255 repeat 5 qgetpos myball(cnt), px,py,pa qcnvaxis lpx, lpy, px, py, 0 x = 60.0+10.0*cnt y = 30.0 qcnvaxis lx, ly, x, y, 0 line lx, ly, lpx, lpy loop qdraw ; オブジェクトの描画 redraw 1 ; 画面の更新を終了 await 12 ; 一定時間待つ goto *main