class IntObj2D { IntEnv2D env; //環境 float x, y; //位置 float vx, vy; //速度 float ax, ay; //加速度 float m; //質量 float eng; //エネルギー boolean strk; //ストロークを描画するか boolean fil; //塗りつぶすか color col_strk; //ストロークの色 color col_fill; //fillの色 boolean enable_drag; //マウスでドラッグ可能か boolean enable_collision; //衝突可能か boolean fixed; //固定されているか float conf_rate; //衝突係数 float fric_rate; //摩擦係数(接触対象との積) float fric_rate_org; //摩擦係数(単体) float stop_vel; //停止速度の閾値 boolean on_drag, on_collision, stopped; //ドラッグ中、衝突中、停止中 float px, py, pvx, pvy; //前回の位置、速度 float mdiffx, mdiffy; //ドラッグ中のマウス座標と中心位置の差 int obj_type; IntObj2D (IntEnv2D in_env, float in_x, float in_y, float in_m , boolean in_strk, color in_col_strk, boolean in_fil, color in_col_fill , int type){ init_param(); env = in_env; x = px = in_x; y = py = in_y; m = in_m; strk = in_strk; fil = in_fil; col_strk = in_col_strk; col_fill = in_col_fill; obj_type = type; calc_eng(); } void init_param(){ env = null; x = y = vx = vy = ax = ay = 0; m = 1; eng = 0; col_strk = color(128); col_fill = -1; enable_drag = enable_collision = true; fixed = false; conf_rate = 0.9; fric_rate = fric_rate_org = 50; stop_vel = 1; on_drag = on_collision = stopped = false; pvx = pvy = px = py = 0; mdiffx = mdiffy = 0; } void calc_eng(){ eng = m * env.gravMag(x, y) * env.altitude(x, y) + m * ( vx*vx + vy*vy ) / 2; } boolean mouseop(float mx, float my, boolean pressed, boolean clicked){ if(enable_drag){ if( over(mx, my) && clicked && !on_drag ){ on_drag = stopped = true; env.boundX(this); env.boundY(this); px = x; py = y; vx = vy = pvx = pvy = 0; mdiffx = mx - x; mdiffy = my - y; } else if( pressed && on_drag ){ //位置の更新 x = mx - mdiffx; y = my - mdiffy; env.boundX(this); env.boundY(this); //速度の更新 if( env.dt != 0 ){ float cvx = (x - px) / env.dt; float cvy = (y - py) / env.dt; //一つ前の速度と平均を取る vx = (cvx + pvx) / 2; vy = (cvy + pvy) / 2; pvx = cvx; pvy = cvy; } else{ vx = vy = 0; } px = x; py = y; } else if( !pressed && on_drag ){ on_drag = stopped = false; calc_eng(); } else return false; return true; } else return false; } void update(){ //加速度、速度、位置の更新 if( !fixed && !on_drag && !stopped ){ //加速度の更新 update_accel(); //速度の更新 vx += ax * env.dt; vy += ay * env.dt; //位置の更新 x += vx * env.dt; y += vy * env.dt; //println(x+" "+y+" "+z); //静止のチェック if( mag(vx, vy) < stop_vel && ( env.gravMag(x, y) == 0 || on_collision ) ){ stopped = true; vx = vy = 0; ax = ay = 0; } } on_collision = false; } void update_accel(){ float fric = env.fric(x, y, vx, vy) + ( on_collision ? fric_rate : 0 ); float vv = mag(vx, vy); if( vv > 0 ){ ax = env.gravX(x, y) - (fric * vx / vv) ; ay = env.gravY(x, y) - (fric * vy / vv) ; } else{ ax = env.gravX(x, y); ay = env.gravY(x, y); } //println("a "+ax+" "+ay); } //以下のメソッドは派生クラスでオーバーライドする boolean over(float mx, float my){ return false; } void disp(){ } }