衝突4

クリックでアニメーションが始まります。

めり込み補正の観察

 広くゆとりのある空間では普通に動作しているように見えるが、狭い空間にぎゅっと押し込められると事情が違ってきます。

変更なし

 教材どおり、衝突物体AB双方に1/2ずつめり込み補正をかけた場合の動作です。
 混雑した時にわしゃわしゃとなってしまいます。
 時間の経過と共に徐々に収まっていきますが、わしゃわしゃとならない方法を探しています。
  //めり込み補正
  PVector vec = PVector.sub(obj[i].pos, obj[num].pos);
  vec.mult(e / 2);
  obj[num].pos.add(vec);
  obj[i].pos.sub(vec);

<collision4A.pde>

パターン1

 片方のみにめり込み補正を任せた場合の動作です。
 教材には双方に半分ずつ負担させろと書いてあったのですが、当初は手抜きでこの処理を採用していました。
 押し戻すことが出来ないため収拾がつきません。
  //めり込み補正
  PVector vec = PVector.sub(obj[i].pos, obj[num].pos);
  vec.mult(e);
  obj[num].pos.add(vec);

<collision4B.pde>

迷走

 完成形を得るまでに多くの失敗をしました。
 めり込み補正を画面中央に向かって行うというその場しのぎの変なことを考えたこともありました。
 現状をしのぐ方法ばかり考えていた中で最後にたどり着いたのは万能型だと思います。
 ただ、どこかで見たことのある動きなので、すでに誰かがやっていることを思い出しただけかもしれません。

完成

 フレームレートを下げているのはコマ落ち回避のためなので、1フレームをn分割して計算回数のみ増やし、上げた状態を擬似的に再現してみる。

24分割(=12*24=288fps)
 V

 5分割辺りから回復力の向上、10分割辺りでわしゃわしゃ回避の効果が見られました。
 分割数を増やせばより効果がでますが、当然処理が重くなります。上の条件ですと100分割ほどでめり込まなくなる模様です。
 はねかえり係数の影響も大きく、1に近いと速度が吸収されないので跳ね回るし、0に近いと圧縮されやすくなり、フレーム分割数を大きくする必要がでてきます。
int frameDiv = 24;//1フレームの分割数
...
  for(int t; t < frameDiv; t++){
    for(int i; i < obj.length; i++){
      obj[i].act(i);
...
  pos.add(PVector.div(spd, frameDiv));

<collision4C.pde>

 本当にきれいにするには、ビリヤードのブレークショットのような状態を計算する必要があるらしく、今のところその方法は見当もつきません。