衝突2

UFOの動き


    //加速減速
    if (dist(sx, sy, 0, 0) < 1){
      sx = random(-20, 20);
      sy = random(-20, 20);
    }else{
      int b = 0.85;
      sx *= b;
      sy *= b;
    }

<collision2A.pde>

 というより、あめんぼうでした。
 これに前回の衝突と、今回はめり込み回避を付けたいと思います。

一手戻す

 衝突した際に衝突前の位置に移動して止めてみます。
    //衝突判定
    for(int i = 0; i < obj.length; i++){
      if ((dist(obj[num].px, obj[num].py, obj[i].px, obj[i].py) < (obj[num].d + obj[i].d) / 2) && (i != num)){
        px -= sx; py -= sy;
        sx = 0; sy = 0;
      }
    }

<collision2B.pde>

 何もしなかった頃と比較すると衝突の雰囲気はあります。ぴたりと止まると美しいけれど、隙間が少し気になります。

衝突位置まで戻す

 したいところですが、調べてみたところ計算が複雑らしく、自分で計算したところ、二次方程式を解く必要がある(こちらとあちらの座標だと思う)ので、多く利用されている中心を結ぶ線上でのめりこみ補正を実施します。

  //めり込み補正
  float c = 1 - (obj[num].d + obj[i].d) / 2 / dist(obj[num].px, obj[num].py, obj[i].px, obj[i].py);
  px += (obj[i].px - obj[num].px) * c;
  py += (obj[i].py - obj[num].py) * c;

<collision2C.pde>

 衝突時に滑りながら回り込むことは予想外の動きでしたが、美しいのでこれはこれでありだと思います。

衝突判定を付ける

 最後に本命である衝突処理を加えます。
 PVectorクラスが用意されているので、座標の類はすべてそれを利用するように修正しました。
 Javaに関する知識を少し獲得したので、それに関する点を修正しました。
void collision(obj1, obj2){
  //v'1 = -1 * m2 * (1 + e) / (m1 + m2) * Dot(v1 - v2, c) * c + v1;
  //v'2 = m1 * (1 + e) / (m1 + m2) * Dot(v1 - v2, c) * c + v2;
  //共通
  PVector cv = PVector.normalize(PVector.sub(obj2.pos, obj1.pos));
  cv.mult((1 + 0.25) / (obj1.m + obj2.m) * (PVector.sub(obj1.spd, obj2.spd)).dot(cv));
  //v'1
  obj1.spd.add(PVector.mult(cv, -1 * obj2.m));
  //v'2
  obj2.spd.add(PVector.mult(cv, obj1.m));
}

<collision2D.pde>

 予想以上にきれいな結果が得られて大満足です。難しいと思ってあきらめていましたが、よい教材にめぐり合えてよかったです。