2011-07-17 50 views
0

我有這個簡單的歐拉集成商。爲了找到精確的碰撞時間,它也應該處理負的dt(我將幀時間分開,並在檢測到碰撞時模擬回來)。簡單的歐拉物理,奇怪的行爲

出於某種原因

someBody.update(1.0); 
someBody.update(-0.3); 
someBody.update(-0.3); 
someBody.update(0.6); 

給出比不同的結果:

someBody.update(1.0); 

這可能是因爲我用歐拉,而不是RK4或verlet的?

下面的代碼爲積分:

void Body::update(double dt) 
{ 
    if (dt > 0) velocity += acceleration * (dt*dt); 
    else velocity -= acceleration * (dt*dt); 
    pos += velocity * dt; 
    rotation += angularVelocity * dt; 
} 

非常感謝!

馬騰

+1

爲什麼'velocity + = acceleration *(dt * dt);'? $ v =不是$? –

+0

請檢查'someBody.update(1.0);'是否會產生與'someBody.update(0.5)相同的值; someBody.update(0.5);'我不認爲你現在的公式做得對。還要檢查在x = 0,v = 0,a = 1時,在someBody.update(1.0)之後;'你會在x = 0.5,v = 1。 – Sjoerd

回答

3

原因是數學。讓我們關注velocity變量:

如果您撥打:

someBody.update(1.0)

你會得到:

velocity += acceleration * 1

但是,如果你撥打:

someBody.update(1.0); 
someBody.update(-0.3); 
someBody.update(-0.3); 
someBody.update(0.6); 

你將得到:

velocity += acceleration * (1 - 0.3^2 - 0.32^2 + 0.6^2)

(這給velocity += acceleration * 1.18

你應該簡單地velocity += acceleration * dt;

+0

感謝Martinho加入正確的答案,我甚至沒有考慮過物理本身。 – tomasz

0

可疑浮點錯誤在身體積聚::更新。例如:1 + 2 + 3 + 4 = 10,但1.0 + 2.0 + 3.0 + 4.0 =其他。

最簡單的解決方法是在每個主要計算步驟之後舍入結果。

0

謝謝,加速確實是錯誤的。

我爲每個幀使用固定的時間步長。此功能用於運行部分幀的模擬。所以我現在完全忽略了accaleraion。這樣一個框架內的所有內容都是線性發生的,而加速只能在兩幀之間添加。

雖然問題依然存在。我認爲這可能是由Magicianeer指出的浮點錯誤。

雖然我認爲這些錯誤不會如此顯着地加起來。在大約50幀的時候,彈跳對象從完全高度(100)降至大約一半高度。在200幀左右,它仍然在地板上。當我不在框架中調用多個更新時,它都很好。

我會盡量保留幀的末尾位置,並在完成部分幀模擬後將其放回原位。這樣錯誤不會疊加在多個幀上。