class IntEnv2D { PApplet ap; float x1, y1, x2, y2; float grav; float fric_bound; float dt, fps; IntObj2D[] objs; //オブジェクトタイプの定数 final int TYPE_BALL = 0; IntEnv2D(PApplet iap, float ix1, float iy1, float ix2, float iy2, float framerate){ ap = iap; x1 = ix1; y1 = iy1; x2 = ix2; y2 = iy2; fps = framerate; dt = 1 / fps; grav = 800; fric_bound = 50; objs = new IntObj2D[1]; objs[0] = new IntBall2D(this, (x2+x1)/2, (y2+y1)/2, 20, color(100, 80, 240, 150)); //objs[0].conf_rate = 1; } void update(){ int i, j; //時間変位 // #windowsのtimerは10msの精度しかないのでProcessingが // #持っているframeRateを使って計算 dt = 1 / frameRate; boolean fk = false; //ボールのマウス操作 for(i=0; i 0 && vv > 0) adj_vel = sqrt(vv) / v; } if(bx) b.vx *= - b.conf_rate * adj_vel; if(by) b.vy *= - b.conf_rate * adj_vel; if(bx || by){ b.calc_eng(); b.on_collision = true; b.fric_rate = b.fric_rate_org + fric_bound; } } } void collision(IntObj2D o1, IntObj2D o2){ if( !o1.enable_collision || !o2.enable_collision ) return; IntBall2D b1, b2; if( o1.obj_type == TYPE_BALL && o2.obj_type == TYPE_BALL ){ b1 = (IntBall2D) o1; b2 = (IntBall2D) o2; //ボール1の中心からボール2の中心へのベクトル float px = b2.x - b1.x; float py = b2.y - b1.y; //中心間の距離 float dd = dist(0, 0, px, py); if( dd <= b1.r + b2.r ){ b1.on_collision = b2.on_collision = true; b1.fric_rate = b2.fric_rate = b1.fric_rate_org + b2.fric_rate_org; b1.stopped = b2.stopped = false; //中心間のベクトルがx軸になす角度 float theta = atan2(py, px); float sint = sin(theta); float cost = cos(theta); //ボール1の速度ベクトルを-theta回転 float tvx1 = cost*b1.vx + sint*b1.vy; float tvy1 = - sint*b1.vx + cost*b1.vy; //ボール2の速度ベクトルを-theta回転 float tvx2 = cost*b2.vx + sint*b2.vy; float tvy2 = - sint*b2.vx + cost*b2.vy; //ボールid,iの質量 float m1 = b1.m; float m2 = b2.m; float conf = b1.conf_rate * b2.conf_rate; //運動量保存の法則により衝突後の速度ベクトルを求める float tvx1n = ( ( m1 - conf*m2 ) * tvx1 + m2 * ( 1 + conf ) * tvx2 ) / ( m1 + m2 ); float tvx2n = ( m1 * ( 1 + conf ) * tvx1 + ( m2 - conf*m1 ) * tvx2 ) / ( m1 + m2 ); //速度ベクトルをtheta回転して速度の更新完了 b1.vx = cost*tvx1n - sint*tvy1; b1.vy = sint*tvx1n + cost*tvy1; b2.vx = cost*tvx2n - sint*tvy2; b2.vy = sint*tvx2n + cost*tvy2; //位置の更新(ボール同士が重なったままにならないように) //質量が小さい方のボールが逃げるように調整 if(b1.fixed){ b2.x += (b1.r + b2.r - dd) * px / dd; b2.y += (b1.r + b2.r - dd) * py / dd; b1.vx = b1.vy = 0; } else if(b2.fixed){ b1.x += (b1.r + b2.r - dd) * (-px) / dd; b1.y += (b1.r + b2.r - dd) * (-py) / dd; b2.vx = b2.vy = 0; } else{ b1.x += (b1.r + b2.r - dd) * m2 / (m1 + m2) * (-px) / dd; b1.y += (b1.r + b2.r - dd) * m2 / (m1 + m2) * (-py) / dd; b2.x += (b1.r + b2.r - dd) * m1 / (m1 + m2) * px / dd; b2.y += (b1.r + b2.r - dd) * m1 / (m1 + m2) * py / dd; } //エネルギーを再計算 b1.calc_eng(); b2.calc_eng(); } } } }