【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の製作者、@kassy708さんに面白いお話をうかがうことができました。
@v416 戻す"力"というよりは、例えば時刻t=0の時高さy=10の球が重力加速度g=3で落下するとき地面の高さが0だとすると、球はt=3の時に速度v=-9でy=-8となり地面にめり込みます。その時、反射としてv*=-1の処理を行います。 ...続きます。
2013-01-17 20:20:11 via web to @v416
@kassy708 @v416 この時、めり込んだ球を地面表面に戻す処理を行うと、y=0の時にv=9となります。するとt=6にv=0となり、y=18の高さまで上昇することになります。戻す処理をしなければt=6の時はy=10となります。 とこんな感じで予想してます。
2013-01-17 20:20:51 via web to @kassy708
めり込んだ分、yの座標を補正する。その補正分がαとなっているようなのです。
いやはや、ややこしい話であります。
さて。まとめです。
- 反発係数はぶつかった時に戻ってくるスピードを決定するための値
- 範囲は0.0~1.0
- 係数が異なる同士がぶつかったら、大きい方の係数が採用される
- めり込んだ分の補正が加わる
以上です。
*1:正しくはPhySprite.enchant.js