最近在編寫一些簡單的物理引擎,在編寫靜態碰撞的時候遇到了小問題,經人指點後終於弄懂了,如今寫出來分享下。算法
物理引擎主要是用來模擬大天然的力的做用。在我看來,物理引擎主要有兩個機制:動畫
這裏扯一個題外話,在計算機動畫裏,特別是物理引擎中主要處理的是質點的位置和速度,不少大天然的物理都是近似當作由多個質點組成的。因此,碰撞主要解決的是三類問題:spa
在計算機圖形學中,咱們能夠利用OpenGL等圖形API在三維場景中繪製一些三維圖形,好比地面、桌子、小球等。可是計算機自己不知道什麼是地面,什麼是桌子,因此在當咱們給地面上添加一個受重力做用的靜止小球,咱們看到的只會是小球一直下落,而不是靜止在地面上。固然咱們能夠加一些幾何約束(y<0時,y=0),強行讓小球在地面上,可是咱們用物理引擎模擬顯然不能作,咱們能夠將這種狀況模擬成碰撞,這一類的碰撞都稱爲靜態碰撞。如圖1,能夠看第2幀的時候小球位於地面下面,咱們能夠認爲這時小球是與地面相交的,生成碰撞。 rest
圖1orm
咱們確定不但願咱們的程序中物體沒有靜止在地面上,反而穿過地面繼續下墜。咱們須要對碰撞行爲進行檢測。如上圖,咱們能夠看出在第1幀狀態下,小球的位置是沒有問題,但到了第2幀,小球與地面相交了。因此咱們要尋找一個經過兩幀的碰撞信息就能判斷出第1幀狀態下小球是不是靜止的。咱們結合上圖分析,由於小球只受到重力做用,即小球的速度僅由其重力引起,對此,可簡單的將多用力乘以第1幀和第2幀之間的時間間隔(duration),進而獲得基於當前做用力下的速度數據,這個速度咱們寫做Vg。因爲咱們將小球做碰撞處理,因此由碰撞機制能夠獲得小球在第2幀的真實速度V。咱們比較Vg和V,若是實際速度V小於Vg,則可知小球在第1幀中處於靜止狀態。blog
那麼問題來了,爲何比較這兩個速度就能夠肯定小球在前一幀就是靜止狀態?咱們結合圖2來分析一下。在小球第1幀靜止在在地面V=0,可是咱們計算一下若是按碰撞處理的話,小球確定會產生一個方向向上的速度V'。這時咱們再跟Vg進行比較,V'<Vg,說明小球並無向上運動的趨勢,因此小球的初始前一幀狀態要麼是靜止要麼是速度很是很是小,均可以近似做靜態碰撞處理。ci
圖2it
最後貼一段處理這個過程的代碼。io
double newSepVelocity = -separatingVelocity * restitution; CVector3 accCausedVelocity = particle[0]->GetAcceleration(); if (particle[1]) accCausedVelocity -= particle[1]->GetAcceleration(); double accCausedSepVelocity = accCausedVelocity * contactNormal * duration; /*比較合外力產生的速度和碰撞後物體的速度*/ if (accCausedSepVelocity < 0) { /*newSepVelocity爲正值*/ newSepVelocity += restitution * accCausedSepVelocity; if (newSepVelocity < 0) newSepVelocity = 0; }