【enchant.js】Hello Physical World vol.2【box2d】

さて。
お待たせしました。「Hello Physical World」2回めです。
今回はちょっとやっかいな反発係数を取り上げようと思います。

反発係数とは! 2物体の衝突において、衝突前の互いに近づく速さに対する、衝突後の互いに遠ざかる速さの比のことである

ようするに、物体が跳ね返ってきた時の、元のスピードとの比率ってわけですね。
例えば10mm/sで飛んでいった物体が、壁にぶつかって8mm/sで戻ってきたとする。その時の反発係数は10:8、つまり0.8となります。式にするとこんな感じですね。

戻ってきた時のスピード = 元のスピード * 反発係数

反発係数は、通常0.0~1.0の値を取ります。プログラム上、2.0とか設定出来ますが、それは10mm/sで飛んでいった物体が20mm/sで戻ってくるとかステキな結果が待ってます。

まず前回のコードを引っ張り出してきましょう。そんでもって床の反発係数を0.0にしてみて下さい。

floor = new PhyBoxSprite(320, 16, enchant.box2d.STATIC_SPRITE, 1.0, 0.5, 1.0, true);

これを

floor = new PhyBoxSprite(320, 16, enchant.box2d.STATIC_SPRITE, 1.0, 0.5, 0.0, true);

こんな感じですね。動きに変化は感じられないですね。
続いて床の反発係数を1.0に戻し、リンゴの反発係数を0.0にしてみて下さい。

var apple = new PhyCircleSprite(8, enchant.box2d.DYNAMIC_SPRITE, 1.0, 0.5, 0.0, true);

これも動きが変わりませんね。

はい、重要なポイント。
反発係数は値の大きな方が採用され、小さな方は無視されます。
これはBox2Dの基本的な動きなので覚えておいて下さい。


……さて。
みなさまのお手元で実行中のプログラム、リンゴはどこへ行ったでしょうか? そろそろ画面の外に飛び出している頃じゃないでしょうか。
私、冒頭でこう書きましたよね?

戻ってきた時のスピード = 元のスピード * 反発係数

しかしこの動きはどう見てもこうです。

戻ってきた時のスピード = 元のスピード * 反発係数 + α

「ウソつき!」って声が聞こえてきそうです。
ウソなんですよ! 私もびっくりしましたよ! 「運動量保存の法則」無視ですよ! 永久機関の完成ですよ!

果たしてこのαはどこから来るのか? box2d.enchant.js*1の製作者、@さんに面白いお話をうかがうことができました。



めり込んだ分、yの座標を補正する。その補正分がαとなっているようなのです。
いやはや、ややこしい話であります。


さて。まとめです。

  • 反発係数はぶつかった時に戻ってくるスピードを決定するための値
  • 範囲は0.0~1.0
  • 係数が異なる同士がぶつかったら、大きい方の係数が採用される
  • めり込んだ分の補正が加わる

以上です。

*1:正しくはPhySprite.enchant.js