指数関数を使ったお手軽イーズ・アウト

(この記事にはProcessing.jsによるスケッチがいくつか組み込まれています。環境によっては正しく再生されないかもしれません。Chrome, Safari, Firefox等の使用をおすすめします。)

「丸が1秒おきに左右に滑らか動く」というプログラムを書いてみよう。いちばん簡単なのは、線形移動を使う方法だ。

まあ、これでも十分っちゃ十分なんだけれど、動きとしてはちょっと味気ない。

いわゆるイーズアウト(ease out)を使えば、これを滑らかにすることができる。

上のスケッチでは、漸化式を使ったイーズアウトを実装している。こんな感じの式だ。

pos += (target - pos) * 0.1;

pos は現在座標、 target は目標の座標。この式を1回の描画毎に評価する。目標座標までの差分を1割づつ詰めていくような感じ。差分は毎回少なくなっていくから、最初は早く、徐々に遅く、という動きが出来上がるわけ。

この動きは、数式的には指数関数で表すことができる。グラフにプロットすると、だいたいこんな感じだ。

この方法は、特に変数を追加しなくても実装できるというのがいいところだ。

ただ、この方法には致命的な弱点がある。それは、フレームレートによって動きが変化してしまうということだ。例えば、上のスケッチのフレームレートを10に落とすと、下のようになる。

動きの勢いが違うし、しかも時間内に目標座標まで到達できていない。

これはフレームレートが変化しうる条件下では致命的な欠点だ。UIなら操作のフィーリングが変わってしまうし、ゲームなら難易度が変化してしまうかもしれない。

この問題を解決するには、上で例示した指数関数を、フレームレートを含んだ形で漸化式に直せばいい。過程は省略するけれど(高校数学の指数関数を思い出して!)こんな感じの式になる。

pos += (target - pos) * (1.0 - exp(-6.0 * deltaTime));

このスケッチのフレームレートを10に落とすと、下のようになる。

フレームレートを落としたために、動きの滑らかさは無くなってしまっているけれど、だいたいの動きとしては同じになっているし、同時刻に目標座標に到達することができている(これはとても重要な性質)。

少しばかり式は複雑になったけれど、変数を追加しなくても実装できるというお手軽さは変わらない。即席的に動きを改良したくなった場合におすすめできる方法だ。

  1. park-heim reblogged this from radiumsoftware
  2. takcom reblogged this from snk1
  3. snk1 reblogged this from radiumsoftware
  4. codesamplr reblogged this from radiumsoftware
  5. miyamya reblogged this from radiumsoftware
  6. deput reblogged this from radiumsoftware
  7. i-q-e reblogged this from redjuice
  8. exposition reblogged this from redjuice
  9. redjuice reblogged this from radiumsoftware
  10. nullpointerexception reblogged this from radiumsoftware
  11. ipomblr reblogged this from tahirose
  12. tahirose reblogged this from radiumsoftware
  13. iyoupapa reblogged this from wonderthinkanswer
  14. sou reblogged this from shimobayashi
  15. kazoo04 reblogged this from radiumsoftware
  16. itakeda reblogged this from kotenpa
  17. tumblr2009tumblr reblogged this from shimobayashi
  18. kotenpa reblogged this from radiumsoftware and added:
    数年前XSIで話題になってた、SoftIK式、ですよね?フレームレート、要注意と。
  19. shimobayashi reblogged this from radiumsoftware
  20. ken0205 reblogged this from wonderthinkanswer
  21. wonderthinkanswer reblogged this from takashi0215
  22. takashi0215 reblogged this from do-nothing
  23. do-nothing reblogged this from radiumsoftware
  24. iwadon reblogged this from radiumsoftware
  25. susatadahiro reblogged this from radiumsoftware
  26. sounanjihen reblogged this from hetmek
  27. rectdz reblogged this from radiumsoftware
  28. hetmek reblogged this from radiumsoftware
  29. nolifedeffounderror reblogged this from kiyo-shit
  30. kiyo-shit reblogged this from radiumsoftware
  31. teppey reblogged this from radiumsoftware
  32. teppey reblogged this from radiumsoftware