LoginSignup
3
2

Bifrostではじめる位置ベース物理シミュ 第2回 ~力を加える・位置を補正する~

Last updated at Posted at 2024-02-06

ハイどうもこんにちは!

前回に引き続き位置ベースでなんちゃって物理をいじくっていきます。

\begin{cases}
v(t) = \frac{x(t) - x(t - \Delta t)}{ \Delta t} \\ 
x(t + \Delta t) = x(t) + v(t) \Delta t +\frac{F}{m} \Delta t^2
\end{cases}

前回、見なかったことにした$\frac{F}{m} \Delta t^2$の部分と、さらにその後、得られた位置を強引に補正する工程を追加していきます。ベースのBifrostグラフは前回組んだものがあるのでちょい足しするだけです。

が、その前に、初期値をvalueノードで入力するのは面倒になってきたのでinputにつなぎ直しておきます。前回の最後のグラフから始めます。
img_02_00.png

inputとoutput以外の全体をコンパウンド化し、以下のように修正します。入力側のフィードバックポートには何も接続してなくて大丈夫です。(接続してもすぐ上書きされます。)出力側のフィードバックポートはしっかりoutputへつないでおきます。

img_02_01a.png
▲bifrostGraphShape

img_02_01b.png
▲bifrostGraphShape > pbd

img_02_01c.png
▲Initial Positionへlocatorなどを接続し、初期位置を自由に動かせるようにしておきます

重力

では本題に戻って重力を足してみます。まず、$\frac{F}{m} \Delta t^2$の$m$は質量、$F$は力、$\Delta t$は前回も書きましたが1ステップの経過時間です。「力(チカラ)ってなんやねん…」と思うかもしれませんがこれも位置や速度と同じくベクトルで表されます。単位は$N[kg \cdot m/s^2]$ですが、まぁ細かいことは気にせず進めましょう。

重力による力は次のように表されます。

F_{gravity} = mg

$g$は重力加速度です。このことから例の式の$\frac{F}{m} \Delta t^2$の部分は次のように置き換えられます。

g \Delta t^2

$g$はどんな質量のものでも約$9.8 [m/s^2]$が標準値とされているので、Y軸下向きにこれをあてはめます。

g = (0, -9.8, 0)

fig_02_01.jpg

ということで、Bifrostグラフに追加します。右下のGravityが追加した部分です。

img_02_02.png
▲bifrostGraphShape > pbd > Verlet(※現在シーンの単位がcentimeterなので-980にしてあります)

初期位置を上空5m(500cm)、初速度を0、dampingを0にして30fpsで再生してみます。
gif_02_02.gif

0Fから開始して30F前後の時、つまり約1秒後に地面に到達しました。念のため、物理の教科書に載っていそうな自由落下の公式 $y = \frac{1}{2} g t^2$ で5mの落下にかかる時間を確認してみます。

\begin{aligned}
y &= \frac{1}{2} g t^2 \\
5 &= 4.9 t^2 \\
t^2 &= \frac{5}{4.9} \\
t &= 1.01015 \\
\end{aligned}

だいたいあってそうですね!

バネ

前項の例では完全にフリーな点を落下させましたが、次は初期位置からバネやゴムのような何かで繋がれているような動きを追加してみます。バネモデルを用いた力は次のように表されます。

F_{spring} = -k \{x(t) - x_0\}

$k$はバネ係数、$x_0$は初期位置です。初期位置から今の位置までのベクトルを$k$倍して反転させるような形になっています。この逆向きの力は初期位置から離れれば離れるほど大きくなります。で、例の式に入れ込むと次のようになります。

x(t + \Delta t) = x(t) + v(t) \Delta t + (g + \frac{F_{spring}}{m}) \Delta t^2

fig_02_02.jpg

これをBifrostグラフに足してみます。バネ係数$k$はelasticity、質量$m$はmassというパラメータにします。先ほどの重力も含めForceという括りでまとめ直しています。
img_02_03.png
▲bifrostGraphShape > pbd > Verlet

初速度を0、dampingを0.05、elasticityを30、massを1にして再生してみます。バネっぽい雰囲気が出てきました!
gif_02_03.gif

また、いくつかパラメータの組み合わせを変えて試してみました。
gif_02_03_compare.gif
左から順に

  • damping: 0.05 / elasticity: 20 / mass: 1
  • damping: 0.05 / elasticity: 100 / mass: 1
  • damping: 0 / elasticity: 30 / mass: 1
  • damping: 1 / elasticity: 30 / mass: 1
  • damping: 0.05 / elasticity: 30 / mass: 0.1
  • damping: 0.05 / elasticity: 30 / mass: 3

補正前の位置に戻す

ここまでの計算で得られた位置を補正前の位置の方向へガッと戻します。ついさっきまで出来るだけ正しそうな重力やバネを表現してたのにお構いなし、強引にやっちゃいます。ナンテコッタイ!

具体的には、補正後の位置から補正前の位置へ向かうベクトルを求め、stiffness値でスケーリングしてから補正後の位置に足します。stiffnessは0〜1の値を入力します。1の時には位置の変化が完全に打ち消され微動だにしなくなります。

x(t + \Delta t)' = x(t + \Delta t) + \{x(t) - x(t + \Delta t )\} * stiffness

fig_02_03.jpg

これをBifrostグラフに足してみます。
img_02_04.png
▲bifrostGraphShape > pbd

先ほどと同じく、初速度を0、dampingを0.05、elasticityを30、massを1、そしてstiffnessを0.15にして再生してみます。さっきよりだいぶ動きが鈍くなりました。
gif_02_04.gif

第2回でやっとここまで来ました。次回は「制約条件」が加わり位置ベースの良いところが見えてきます。

今回のグラフまとめ

bifrostGraphShape
img_02_05a.png

bifrostGraphShape > pbd
img_02_05b.png

重力とバネを加味して次の位置を決定(bifrostGraphShape > pbd > Verlet)
img_02_05c.png

補正前の位置に戻す(bifrostGraphShape > pbd > Keep_position)
img_02_05d.png


前の記事

次の記事

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2