Motion 7, 加速度のコントロール
Nov 20, 2010
さて、これまで紹介した動きはいわゆる等速運動、一定の速度で動く動きです。
次からは、加速・減速の動きのバリエーションを紹介します。
例えば、ボールを放ったときの動きを表現するとします。放られたボールは最初は勢いよく、やがて動きをゆるめて地面に落ちます。
X軸(横移動)に絞って色々試してみます。
これまでの例では、x += speed というステートメントで表現されるような、一定量の座標が加算される動きでした。
var x = 0, speed = 10; // 横座標, 速度 ... x += speed;
速度を徐々にゆるめたいときもっとも単純なのは、速度を減算で減らすという方法です。
const DECELERATION = 1; // 減速 var x = 0, speed = 10; // 横座標, 速度 ... x += speed; // 速度分移動 speed -= DECELERATION; // 速度を落とす if (speed < 0) return false; // 速度が0になったらアニメーション終了
しかしこの方法だと、到達位置が成り行きになってしまいます。それはそれでいいのですが、例えば到達位置ありきの動きにしたい場合、これだと計算がややこしくなります。そこで考えられるのが、現在位置と到達位置の間隔を割り算で削る方法です。
const START_X = 0, END_X = 100, DECELERATION = .8; // 開始・終了座標, 減速 var x, distance = END_X - START_X; // 横座標, 間隔距離 ... distance *= DECELERATION; // 間隔を割り算する x = END_X - distance; // 終了座標から間隔を差し引いて現在座標を計算 if (distance < 0.1) return false; // 間隔がほぼ0になったらアニメーション終了
しかしこの方法にはちょっと問題があります。いわゆるアキレスと亀の問題で、間隔が無限に縮まるだけで決して到達位置になる事はありません。従って、ほぼほぼ到達位置になったらアニメーションを止める、という処理が必要になるかもしれません。また到達位置に近づくにつれ、動きは極端にゆっくりになります。
三角関数で表現しようとするとちょっと複雑です。
サインは、0°から90°(0.5π)に移るあいだに、0から1まで丸みのある数字(最初にグンと増え、1に近づくにつれゆるくなる)を出します。この性質を利用して、角度を時間、サインの値を距離に置き換えて表現します。
const START_X = 0, END_X = 100, DURATION = 100; // 開始・終了座標, 継続時間 const WHOLE_RAD = Math.PI * 0.5; // 90°に相当する弧度 var elapsed, x, radian; // 経過時間、横座標, 弧度 ... radian = WHOLE_RAD * (elapsed / DURATION); // 現時刻の相対値を弧度に変換 x = Math.sin(radian) * (END_X - START_X); // 座標の計算 if (elapsed == DURATION) return false; // 経過時間が満了したらアニメーション終了 elapsed++; // 時間経過
それぞれ、実際に動かしてみます。
クリックすると動きだします
uni
sub
div
sin
uni が等速運動(uniform)、sub が引き算(subtraction)、div が割り算(division)、sin がサインでの動きです。
どの方法がよいかは状況次第だけど、動きをしっかりコントロールしたい場合は、位置と時間をきちんと把握できるサイン方式になるでしょうか。
Comments