Physics & constraints

Runge–Kutta / RK2 / RK4

ルンゲ・クッタ法

途中の傾きも評価して軌道を計算する。

3 / 10

Interactive demo

Preparing the demo…

Runge–Kutta / RK2 / RK4

Drag to orbit, Ctrl/⌘ + scroll to zoom. Use two fingers on touch screens.

This explanation is currently available in Japanese.

ひとことで

1 ステップ進む間に、途中の何か所かで「進むべき向き」を調べ、それを平均して進むことで、大きな時間刻みでも正確に軌道を追う方法です。今いる場所の向きだけでまっすぐ進むオイラー法は、曲がった道では必ず外へはみ出しますが、4 次のルンゲ・クッタ法(RK4)は 4 回調べるだけで誤差を劇的に小さくできます。

ゲームでの使いどころ

  • 流れに乗る粒子:カールノイズやフローフィールドの中で煙や葉を流すとき、オイラー法では渦の中心から粒子が外へ逃げていきます。RK2 や RK4 なら渦の形に沿って回ります。
  • 軌道の予測線:宇宙船の軌道、砲弾の弾道、ゴルフボールの落下点の予測など、何秒も先まで一気に計算したい場面で、少ないステップ数で正確な線を引けます。
  • 流線の描画:ベクトル場の流線(線積分畳み込みなど)や、磁力線のような可視化。
  • カメラや乗り物の経路:速度場から位置を求める計算全般。

しくみ

dxdt=f(x)\dfrac{d\mathbf{x}}{dt} = \mathbf{f}(\mathbf{x})(場所ごとに進む向きと速さが決まっている)を、時間刻み hh で解くとします。

オイラー法:今の場所の傾きで進む。誤差は hh に比例(1 次)。

xn+1=xn+h f(xn)\mathbf{x}_{n+1} = \mathbf{x}_n + h\,\mathbf{f}(\mathbf{x}_n)

RK2(中点法):いったん半歩進んだ所の傾きを調べ、その傾きで 1 歩進む。誤差は h2h^2 に比例(2 次)。

k1=f(xn),k2=f(xn+h2k1),xn+1=xn+h k2\mathbf{k}_1 = \mathbf{f}(\mathbf{x}_n), \qquad \mathbf{k}_2 = \mathbf{f}\big(\mathbf{x}_n + \tfrac{h}{2}\mathbf{k}_1\big), \qquad \mathbf{x}_{n+1} = \mathbf{x}_n + h\,\mathbf{k}_2

RK4:始点、中点(2 回)、終点の 4 か所で傾きを調べ、中点を重く見て平均する。誤差は h4h^4 に比例(4 次)。

k1=f(xn),k2=f(xn+h2k1),k3=f(xn+h2k2),k4=f(xn+h k3),xn+1=xn+h6(k1+2k2+2k3+k4)\begin{aligned} \mathbf{k}_1 &= \mathbf{f}(\mathbf{x}_n), &\mathbf{k}_2 &= \mathbf{f}\big(\mathbf{x}_n + \tfrac{h}{2}\mathbf{k}_1\big),\\ \mathbf{k}_3 &= \mathbf{f}\big(\mathbf{x}_n + \tfrac{h}{2}\mathbf{k}_2\big), &\mathbf{k}_4 &= \mathbf{f}(\mathbf{x}_n + h\,\mathbf{k}_3), \end{aligned} \qquad \mathbf{x}_{n+1} = \mathbf{x}_n + \frac{h}{6}(\mathbf{k}_1 + 2\mathbf{k}_2 + 2\mathbf{k}_3 + \mathbf{k}_4)

「4 次」とは、時間刻みを半分にすると誤差が 1/161/16 になるという意味です。1 ステップの計算は 4 倍になりますが、同じ精度ならオイラー法よりずっと大きな刻みで済むので、多くの場合トータルで得をします。

速度と位置の両方を持つ運動(物体の運動方程式)では、状態を (x,v)(\mathbf{x}, \mathbf{v}) の組にし、f\mathbf{f} を「位置の変化 = 速度、速度の変化 = 加速度」として同じ式で解きます。

実装のポイント

  • GPU の粒子なら RK2 で十分なことが多い:シェーダーで場を 2 回サンプリングするだけで、渦の中心から逃げる問題はほぼ解消します。
  • 途中で状態を書き換えない:k2∼k4\mathbf{k}_2 \sim \mathbf{k}_4 を求める途中の位置は「試しの位置」です。衝突判定や拘束は、1 ステップ終わってから行います。
  • 剛体の物理エンジンには使わないことが多い:衝突や拘束があると、途中の評価点での力が意味を持たなくなり、4 次の精度が生かせません。ゲームの剛体は半陰的オイラー法が主流です。

つまずきやすい点

  • RK4 でもエネルギーは保存しない:誤差は非常に小さいものの、何千周も回すとじわじわずれます(シンプレクティックではない)。長時間の軌道計算では、刻みを小さくするか、専用の方法を使います。
  • 場が不連続だと効果がない:傾きが急に変わる場所(壁や格子のセルの境目)をまたぐと、高次の精度は失われます。
  • コストの見積もり:「RK4 は重い」と思われがちですが、評価が軽い場なら、刻みを 4 倍にできれば同じコストです。精度と速度の両方で比べます。

デモで試すこと

  1. 本当の道筋は白い点線の円です。赤(オイラー法)は 1 周ごとに外へずれ、黄(RK2)は少しずつ、青緑(RK4)はほとんどずれません。左下に半径のずれが出ます。
  2. 「時間刻み h」を 0.8 まで上げると、オイラー法はすぐに飛び去り、RK2 もずれ始めますが、RK4 は円の上に残ります。0.05 まで下げると、3 つともほぼ重なります。
  3. 「RK4 が傾きを調べる場所」の矢印は、最後の 1 ステップで調べた 4 か所の向きです。始点・中点 2 回・終点で少しずつ向きが違うのが分かります。
  4. 「2 つの渦」に切り替えると、正解が円ではない複雑な道筋でも、RK4 が白い線に沿い続けることを確かめられます。

References

Gaffer On Games — Integration Basics ↗

A general reference for this subcategory.