2017-05-14 103 views
1

我正在用C++寫一個粒子模擬器。幀率獨立加速/減速?

我通過在每個時間步將它們的速度添加到它們的位置來移動粒子。

時間步的值是當前幀的百分比。所以全幀時間步長是1,半幀時間步長是0.5,季度幀時間步長是0.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(速度* = 0.95)的公式? – Tyson

+0

@Tyson:這不是一個減速公式。所以沒有正確的方法將其轉化爲減速。我會建議玩數字,直到你看到一個看起來和感覺正確的值。 –

+0

不是嗎?它描述了速度隨時間的變化,即減少。我想我希望得到一個數學解決方案,而不是'一直到它有效'的解決方案。 – Tyson

0

接受的答案是好的,但我想強調的是,你永遠無法完全獨立的模擬步長。

運動方程(給我們在某個時間點的位置和速度)是積分。模擬通過在小步驟上進行彙總來近似整合。但是因爲這些步驟是有限的而不是無限小的,所以總會有錯誤。您可以製作的步驟越小,您可以減少錯誤的次數越多。

對於視頻遊戲和用戶界面動畫,幀速率順序(例如每秒10-100步)的時間步長通常足以將錯誤保持得足夠小,以至於它對動畫的外觀沒有不利影響或遊戲的可玩性。

但是,如果你運行在每秒都在10分100步相同的模擬,可以得到不同的結果,因爲後者比前者更好的近似。

製作步驟較小也增加了計算量。有時,你沒有足夠的馬力來使用足夠小的步驟來保持錯誤。對於這些情況,有數值積分器,這些積分器給出比重複和更好的近似值。最有名的數值積分器可能是Runge-Kutta (RK4)。如果你發現你必須設置你的timeStep不切實際小,請嘗試使用RK4。