サイトトップ

Director Flash 書籍 業務内容 プロフィール
 

HTML5 / Flash ActionScript講座
Webクリエイターのための
CreateJSスタイルブック
gihyo.jp連載
「HTML5のCanvasでつくる
ダイナミックな表現
―CreateJSを使う」
■Twitter: @FumioNonaka / Facebook Page: CreateJS

Creators MeetUp

速度から位置を決めるアニメーション
  ー 実は微分から運動を考えること

物理的なアニメーションを表現しようとするとき、速度から位置を決めることがよくある。直接位置を計算しようとするより、速度から導いた方が複雑なアニメーションも簡潔に表せたりするからだ。これは数学的には、微分から物体の運動を捉えていることになる(RAVCO「運動方程式」参照)。微分の計算そのものはしなくても、考え方を知るだけで見通しはよくなり、応用の幅も広がる。いくつかのアニメーションのサンプルをもとにご説明しよう。

私「位置→速度→加速度という三つの量。位置の変化が速度。速度の変化が加速度」

... [中略]...

私「さっきの話に戻るけれど、位置から速度を求めることと、速度から加速度を求めることは、数学的には同じだ」
長男「へえ」
私「この計算が、微分なんだ」

引用: 結城浩「位置・速度・加速度

01 等速直線運動

位置(x)は時間(t)に比例(a)して直線上を動く。初めの位置を0とすると、つぎの1次式で表される。

x = at

スクリプティングでは時間の単位をフレームにすると扱いやすい。毎フレーム呼ばれる処理で時間の変数(time)を加算して、上記の1次式で求めた値をオブジェクト(myShape)の座標(y)として与える。

  1. time++;
  2. myShape.y = param_a * time;

しかし、普通このような処理は書かない。時間あたりの位置の変化つまり速度(ピクセル/フレーム)を、毎フレーム位置に加えた方が扱いやすい。

位置 += 速度

数学では一般に、速度(v)は位置を表す方程式の時間(t)による微分(x')として示される。上記1次式を微分すれば定数(a)になる。この値が前掲スクリプトの速度(velocity)だ。つまり、速度を位置に加えれば、運動のアニメーションが表せる。

v = x' = a

等速直線運動でおなじみのスクリプトはつぎの1行で書替えられる。

  1. myShape.y += velocity;

サンプル001■等速直線運動


02 自由落下運動

位置(x)が時間(t)の2乗に比例(a)して落ちるとき、つぎの式で表される(「落体の運動」参照)。なお、初めの位置を0とする。

x = at2
  1. time++;
  2. myShape.y = param_a * time * time;

この場合も、速度から決めた方が扱いやすい。ただし、自由落下運動は2次式なので、速度(v)が時間(t)に比例して増す。この比例係数(2a = A)が加速度だ。

v = x' = 2at = At

フレーム単位のアニメーションで考えると、フレームごとに速度に加速度を足し込む。その速度をさらに位置に加えれば、加速度のついたアニメーションが表せる。

速度 += 加速度
位置 += 速度

この考え方で書替えたのが、つぎのスクリプトだ。自由落下運動の加速度(acceleration)は定数になる。

  1. velocity += acceleration;
  2. myShape.y += velocity;

サンプル002■自由落下運動


03 イーズアウト

イーズアウトの動きは、目標の位置に近づくほど遅くなる(図001)。つまり、目標値と現在値との差に速度を比例させる。なお、比例係数(減速率)は0から1の間の数値とする。

速度 = (目標値 - 現在値) * 減速率   (0 < 減速率 < 1)
位置 += 速度

図001■目標値に近づくほど動きが遅くなる
図001

位置を定める式から速度を求めるのではなく、速度の式を決めてから位置を導く。とくに、動的に目標値が変わるときは、式が立てやすくなる。

  1. var velocityX = (stage.mouseX - myShape.x) * ease;
  2. var velocityY = (stage.mouseY - myShape.y) * ease;
  3. myShape.x += velocityX;
  4. myShape.y += velocityY;

サンプル003■イーズアウトの動き


04 バネのように伸び縮みする動き

バネの伸び縮みの動き(単振動)を見せたいときは、三角関数のsinまたはcosを使うのが定石だ(図002)。時間(t)あたりに決まった角度(ω)回転する三角関数(sin)に半径(r)を掛合わせれば位置(x)が求められる。つぎの式は、振動の中心位置を0とする。

x = r・sin(ωt)

図002■三角関数sinに比例した値をオブジェクトの垂直座標に与える
図002
引用: Wikipedia「Harmonic oscillator

参考サンプル■単振動

動的に目標値が変わるので、微分して速度を求めようとしても、扱いやすい式にならない。また、目標値をどこに入れていいのか途方に暮れる。

v = x' = rω・cos(ωt)

そこで、速度の式から決めようと、目標値から遠ざかるほど遅くなる、としたのでは足りない。速度の変化である加速度を考えるとよい。加速度は力だ。目標値から離れると、その遠さに比例して戻る力が強まる。

加速度から速度を求めるには、速度から位置の場合と同じで、値を足し込めばよい。つぎのように係数で調整すれば、バネのように伸び縮みをしながら目標値にたどり着くうごきになる(図003)。

加速度 = (目標値 - 現在値) * 調整係数
速度 += 加速度
速度 *= 減衰係数
位置 += 速度

図003■伸び縮みが減衰して目標値にたどり着くバネのような動き
図003

この考え方で式を組立てると、三角関数は表れず、四則演算だけでバネのような動きがつくれる。

  1. var accelerationX = (stage.mouseX - myShape.x) * ease;
  2. var accelerationY = (stage.mouseY - myShape.y) * ease;
  3. velocityX += accelerationX;
  4. velocityY += accelerationY;
  5. velocityX *= friction;
  6. velocityY *= friction;
  7. myShape.x += velocityX;
  8. myShape.y += velocityY;

サンプル004■バネのような動き

応用サンプル■EaselJS 0.7.1: Smooth Line tuned

数学的な内容に興味をもたれた方は、結城浩「責任を伴う加速装置(前編)」を読まれると理解が深まるだろう。



作成者: 野中文雄
作成日: 2014年7月19日


Copyright © 2001-2014 Fumio Nonaka.  All rights reserved.