2011-08-10 80 views
8

我想模擬自由落體和與地面的碰撞(例如彈跳球)。物體會落入真空中 - 可以省略空氣阻力。與地面的碰撞會導致一些能量損失,最終物體會停止移動。我使用JOGL渲染一個點,這是我的下降對象。重力恆定(-9.8 m/s^2)。重力模擬

我發現了一個歐拉法計算該點的新位置:

deltaTime = currentTime - previousTime; 
vel += acc * deltaTime; 
pos += vel * deltaTime; 

,但我做錯了什麼。點反彈幾次,然後它下移(非常慢)。

這裏是一個僞代碼(初始POS =(0.0F,2.0F,0.0F),初始電平(0.0F,0.0F,0.0F),比重= -9.8f):

display() 
{ 
    calculateDeltaTime(); 
    velocity.y += gravity * deltaTime; 
    pos.y += velocity.y * deltaTime; 

    if(pos.y < -2.0f) //a collision with the ground 
    { 
     velocity.y = velocity.y * energyLoss * -1.0f; 
    } 

} 

達到現實效果的最佳方式是什麼?歐拉方法如何引用恆定加速度方程?

+0

如果您僅將能量損失排除在等式之外,會發生什麼情況? – redbmk

+0

除了Yochai的回答,你可以考慮在你的碰撞情況下將'pos.y'設置爲地平面以避免削波錯誤 –

+0

如果沒有能量損失,該點也會在一段時間後停止反彈,並且它非常緩慢地向下移動。 – Vert

回答

6

由於浮點不會很好地湊合,所以你永遠不會得到實際爲0的速度。你可能會得到類似-0.00000000000001之類的東西。

當距離足夠近時,您需要將其設置爲0.0。 (定義一些三角洲。)

2

要擴大我上面的評論,並回答Tobias,我會在這裏添加一個完整的答案。

經過初步檢查,我確定你正在流血速度快。簡單地說,動能和速度之間的關係是E = m v^2 /2,因此服用導數相對於速度後,你會得到

delta_E = m v delta_v 

然後,根據energyloss是如何定義的,你可以建立delta_Eenergyloss之間的關係。例如,在大多數情況下energyloss = delta_E/E_initial,則上述關係可以簡化爲

delta_v = energyloss*v_initial/2 

這是假設的時間間隔小,讓您與v_initial取代v第一方程式中,所以你應該能夠爲了你的行爲而放棄它。清楚起見,delta_v從您的碰撞區域內的velocity.y中減去,而不是您所擁有的。

至於增加空氣阻力與否的問題,答案取決於。對於較小的初始下降高度,這並不重要,但由於反彈和較高的下降點,能量損失較小。對於1克,1英寸(2.54cm)直徑的,光滑球,我繪製有和沒有空氣摩擦與下落高度之間的時間差:

difference in time with and without air-drag vs. drop height

對於低能量損失的材料(80 - 90 + %的能量保留),我會考慮將它添加到10米和更高的高度。但是,如果水滴不到2-3米,我就不會打擾。

如果有人想要計算,我會分享它們。

+0

+1謝謝你的回答。我認爲這也是一個很好的解決方案。與Vert的原始碰撞實施形成對比的是,您的身體與地面碰撞並在那裏休息(比如枕頭)可能會產生「較軟」的碰撞,而Vert的版本則是有損反彈。當然選擇哪一個取決於所需的物理行爲。你說得對,包括空氣摩擦會是過度的。 –

+0

@Tobias,這也是一個有損的反彈,只是稍微軟一點的反彈。 – rcollyer

+0

@Vert,當我發佈它時我從未注意到,但是我從'delta_v'的結果中刪除了'energyloss'。現在已經修復了。 – rcollyer