2017-05-14 21 views
1

私はC++でパーティクルシミュレータを作成しています。フレームレート独立の加速/減速?

私は、時間ステップごとにその位置に速度を加えることによって粒子を動かします。

タイムステップの値は、現在のフレームのパーセンテージです。したがって、フルフレーム時間ステップは1、半フレーム時間ステップは0.5、クォーターフレーム時間ステップは.25などです。シミュレーションの合計ステップはframeCount/timeStep ...ですので、タイムステップが小さいほど、ステップはシミュレートされます。

タイムステップ間の基本的な動きを維持することは非常に簡単です。式は次のとおりです。私はあまりにも時間をかけて速度を変更しようとしたら

position = position + velocity * timeStep; //10 full frames later, end position is always the same 

しかし、それは数学の私の現在の理解のためにあまりにも複雑になります。たとえば、私がこれを行う場合:

velocity = velocity * .95f; 
position = position + velocity * timeStep; //10 full frames later, end position dependent on time step 

異なる時間ステップの結果はもはや同じではありません。私は、時間ステップを減らして計算したステップの総数を増やしていると、その速度を何度も下げることになり、粒子の最終位置に大きな影響を与えるためです。

異なる時間ステップで同じ結果が得られるように、時間に応じて速度を変更するにはどうすればよいですか?

答えて

2

速度は時間の経過と共に変化します。あなたはあなたの方程式でそれを正しく計算しました。

position = position + velocity * timeStep; 

加速度は経時的な速度変化である。だからあなたは同じ方程式を使うだけですが、それに応じて変数を変更してください。つまり、位置を速度に、速度を加速度に変更します。タイムステップは同じです。

velocity = velocity + acceleration * timeStep; 

あなたは、摩擦をシミュレートする場合は、あなたが何がいくつかの一定の摩擦値と時間ステップで速度を乗算し、加速からこれを引くです。ただし、この値はフレームにのみ使用し、実際の加速値には格納しないでください。

float temp_accel = acceleration - friction * velocity * timeStep; 

次に、temp_accelに従って速度を変更します。

velocity = velocity + temp_accel * timeStep; 

あなたの加速度がゼロである場合、あなたは、式の外にそれを取ることができますが:

float temp_accel = -friction * velocity * timeStep; 
+0

ええと、あなたの関数の加速値は、私の頭文字(de)ccelerationの式(velocity * = .95)からどうすればよいでしょうか? – Tyson

+0

@Tyson:それは減速の式ではありません。したがって、それを減速に変換する正しい方法はありません。私は、あなたが見た目と正しい感じの価値を得るまで、数字で遊ぶことをお勧めします。 –

+0

それじゃない?それは時間の経過に伴う速度の変化、すなわち減少を表す。私は数学的な解決策を期待していたと思います。 – Tyson

0

受け入れ答えは良いですが、私はあなたが完全独立させることはできないことを強調したいですシミュレーションのステップサイズの

運動の方程式(ある時点での位置と速度を与える)は積分です。シミュレーションは小さなステップで合計を行うことで近似積分を行います。しかし、これらのステップは無限大ではなく有限であるため、常に誤りがあります。小さくするほど、エラーを減らすことができます。

ビデオゲームとUIアニメーションの場合、アニメーションの外観に悪影響を及ぼさない程度にエラーを小さく抑えるには、通常、フレームレート、たとえば10-100ステップ/秒のオーダーの時間ステップで十分ですまたはゲームのプレイ可能性を含む。

しかし、同じシミュレーションを毎秒10と100ステップで実行すると、後者が前者よりも優れた近似であるため、異なる結果が得られます。

ステップを小さくすると計算量も増えます。場合によっては、エラーを理由の中で維持するのに十分なステップを使用するのに十分な馬力がありません。これらの状況のた​​めに、数値積分器があり、これは繰り返し合計よりも良い近似を与える。おそらく最もよく知られている数値積分器はRunge-Kutta (RK4)です。 timeStepを実用的に小さく設定する必要がある場合は、RK4を使用してみてください。