物理の時間発展・拘束

ベルレ積分

Verlet Integration

過去位置を利用してロープや布の動きを進める。

2 / 10

インタラクティブデモ

デモを準備しています…

ベルレ積分

ドラッグで視点を回転、Ctrl(⌘)+ スクロールでズーム。タッチ操作は 2 本指です。

ひとことで

速度を持たずに、今の位置と 1 つ前の位置だけを覚えておき、その差を速度とみなして次の位置を決める方法です。位置を直接書き換えても自然に速度へ反映されるので、「点同士の距離を元に戻す」補正をくり返すだけで、ロープ、鎖、布、ラグドールが作れます。

ゲームでの使いどころ

  • ロープ・鎖・吊り橋:点を並べて距離の拘束でつなぐだけで、たわみ、揺れ、物が載ると沈むロープになります。
  • 布とマント:格子状の点を距離の拘束でつなぐと布になります。
  • ラグドール:『ヒットマン』(2000 年)で、Thomas Jakobsen がベルレ積分と距離の拘束でキャラクターの倒れる動きを作ったことで広く知られるようになりました。
  • パーティクル:衝突で位置を押し戻すだけで、跳ね返りの速度が自動的に決まるので、大量の粒子の処理にも向きます。

しくみ

位置 x\mathbf{x} だけで運動方程式を差分にすると、次の式になります(位置ベルレ法)。

xn+1=xn+(xn−xn−1)+a Δt2\mathbf{x}_{n+1} = \mathbf{x}_n + (\mathbf{x}_n - \mathbf{x}_{n-1}) + \mathbf{a}\,\Delta t^2
  • (xn−xn−1)(\mathbf{x}_n - \mathbf{x}_{n-1}) が「前のステップで動いた量」、つまり速度 × 時間刻みの代わりです。
  • 速度を明示的に持たないので、位置を直接直すと、次のステップの速度も一緒に変わります。例えば衝突で床の上へ押し戻すと、前の位置との差(下向きの速度)が小さくなり、自然に止まります。

距離の拘束でロープを作る

  1. 動かす:全部の点を上の式で進めます(重力で落ちる)。
  2. 距離を直す:つながった 2 点の距離が元の長さ LL と違えば、差の半分ずつ両方の点を動かして LL に戻します。固定された点は動かさず、相手だけを動かします。
Δ=∣xb−xa∣−L∣xb−xa∣,xa+=12Δ (xb−xa),xb−=12Δ (xb−xa)\Delta = \frac{|\mathbf{x}_b - \mathbf{x}_a| - L}{|\mathbf{x}_b - \mathbf{x}_a|}, \qquad \mathbf{x}_a \mathrel{+}= \tfrac12 \Delta\,(\mathbf{x}_b - \mathbf{x}_a), \quad \mathbf{x}_b \mathrel{-}= \tfrac12 \Delta\,(\mathbf{x}_b - \mathbf{x}_a)
  1. くり返す:1 本直すと隣がずれるので、全部の拘束を何回も(5〜20 回ほど)くり返し直します。回数が多いほどロープは伸びにくくなります。
  2. 衝突:球や地面にめり込んだ点は、表面まで押し戻すだけです。

この「位置を動かしてから拘束で直す」考え方を一般化したものが位置ベース物理です。

実装のポイント

  • 時間刻みは一定に:式に Δt2\Delta t^2 が入り、前の位置との差を速度として使うので、刻みが変わると速度の意味が変わってしまいます。固定タイムステップで動かします。
  • 減衰は差に掛ける:(xn−xn−1)(\mathbf{x}_n - \mathbf{x}_{n-1}) に 0.99 などを掛けると空気抵抗になります。
  • 速度が必要なとき:音を鳴らす、ダメージを計算するなど、速度が必要な場合は (xn−xn−1)/Δt(\mathbf{x}_n - \mathbf{x}_{n-1}) / \Delta t で求めます。

つまずきやすい点

  • 反復が足りないとゴムのように伸びる:拘束の数が多い(長いロープ、細かい布)ほど、少ない反復では誤差が伝わりきらず、全体が伸びて見えます。反復を増やすか、固定点に近い順に処理します。
  • 重い物と軽い物をつなぐ:両側を半分ずつ動かすと、重い物まで軽い点と同じだけ動いてしまいます。質量の逆数の比で動かす量を分けます。
  • 硬さの調整が難しい:硬さは反復回数と時間刻みで変わってしまいます。物理的な硬さを指定したいときは拡張位置ベース物理を使います。

デモで試すこと

  1. 赤い球をドラッグして橋に載せると、板が沈み込み、ロープ全体がたわみます。離すと橋が弾んで揺れます。
  2. 「左のロープを切る」を押すと、左端の固定が外れ、橋が右の崖にぶら下がって振り子のように揺れます。
  3. 「距離の補正回数」を 1〜2 にすると、ロープがゴムのように伸びてだらりと垂れ下がります。「最大の伸び」の数値も大きくなります。
  4. 「点と速度を表示」をオンにすると、各点の「今の位置 − 前の位置」(速度の代わり)が青緑の線で見えます。

参考資料

Gaffer On Games — Integration Basics ↗

分野全体の資料で、この項目を直接扱っているとは限りません。