指数平滑法によるアニメーションで利用される更新式の導出
背景
記事内に微分方程式とその導出っぽいのが少しだけ出てくるので改めて自分で解いてみる
記事中に出てくる微分方程式を解く
$ x: position, a: target, c: speed
$ \frac{d}{dt}x = (a-x) \cdot c
ターゲットに近づくほど速度が遅くなる
ここでの$ cは$ \dot xとしての速度じゃなくて単なる定数
解く
変数分離法(だっけ?)で変形
$ \frac{1}{a-x} dx = c \, dt
両辺を積分
$ \int \frac{1}{a-x} \, dx = \int c \, dt
$ -\ln \left| a-x \right| = ct + C_1
$ C_1は積分定数
整理する
$ a-x = e^{ -ct + C_1 } = e^{-ct} \cdot e^{C_1}
定数を上書きする
$ C = e^{C_1} とすると $ a-x = Ce^{-ct}
よって
$ x = a - Ce^{-ct}
記事のほうには$ x_0がでてきているので初期値($ t=0で$ x=x_0)として与えてみる
$ x(0) = x_0を先の式に代入して
$ x_0 = a - Ce^{-c \cdot 0} = a - C
$ C = a- x_0
よって
$ x(t) = a - (a-x_0) \cdot e^{-ct}
これで方程式自体は解けているが、元の記事ではここからさらに変形している
いちおう変形できることをたしかめる↓
$ \begin{aligned} x(t) &= a - (a-x_0) \cdot e^{-ct} \\ &= a - a \cdot e^{-ct} + x_0 \cdot e^{-ct} \\ &= a - a \cdot e^{-ct} + x_0 \cdot e^{-ct} +( x_0 - x_0) \\ &= x_0 + a - a \cdot e^{-ct} -x_0 + x_0 \cdot e^{-ct} \\ &= x_0 + (a-x_0)(1-e^{-ct}) \end{aligned}
結果(1)
$ x(t) = x_0 + (a-x_0) \cdot (1 - e^{-ct})
紹介されているコードと似た感じになった
position += (target - position) * (1 - exp(- speed * dt))
最後の変形は +=の更新に合わせるために初期値($ x_0)を前に持ってくるものだったっぽい
というかこれは+=で現在の値を更新していくような操作だから、離散的に書いたほうが性質をよく表すはず
更新式の中で与えられるべきは $ x(0) = x_0ではなくて $ x(t)だよね?
コードのほうも$ tのところにdt使ってるし
変換してみる
連続的な式:
$ x(t) = x_0 + (a-x_0) \cdot (1 - e^{-ct})
微小な時間 $ \delta t を考えて、$ t = \delta tのとき
$ x(\delta t) = x_0 + (a-x_0) \cdot (1 - e^{-c \,\delta t})
$ x_i ($ i= 0,1,2,...) を使って
$ x_1 = x_0 + (a-x_0) \cdot (1 - e^{-c\,\delta t})
$ x_i \rightarrow x_{i+1}のとき
$ x_{i+1} = x_i + (a-x_i) \cdot (1 - e^{-c\,\delta t})
(お気持ち変形で申し訳ない)
結果(2)
$ x_{i+1} = x_i + (a-x_i) \cdot (1 - e^{-c\,\delta t})
これでコードと同じになった
position += (target - position) * (1 - exp(- speed * dt))
つまりposition = position + (target - position) * (1 - exp(- speed * dt))
左辺のposition: $ x_{i+1}
右辺のposition: $ x_i
target: $ a
speed: c
dt: $ \delta t