物理引擎學習04 GJK計算多邊形之間的最近距離

2021-10-24 01:47:05 字數 2734 閱讀 8491

計算多邊形之間的最近距離,才是gjk演算法原本的目的。只有兩個多邊形不相交,計算最近距離才有效。如果相交,則最近距離無效,但是可以使用epa演算法要計算碰撞深度。本文的寫作目的,主要是對gjk演算法的理解和應用。對演算法本身感興趣的朋友,可以閱讀源**的文獻。本系列gjk演算法文章共三篇,本篇是第二篇,強烈建議從第一篇開始看:

3. 小結

4. 參考

計算多邊形之間的距離,本質是在兩個多邊形上找到距離最近的邊,然後計算兩個邊之間的最近距離。計算最近距離的演算法和gjk碰撞檢測演算法類似,同樣使用閔可夫斯基差來構建單形體,使用同樣的support函式。當沒有發生碰撞的時候,距離原點最近的閔可夫斯基差集多邊形的邊,就是我們要計算最近距離的關鍵。為了方便表示,下文將該邊稱作「差集最近邊」。

gjk最近距離演算法的兩個關鍵點為:

需要注意的是,兩個多邊形最近的位置不一定是邊,也可能是頂點。不過這種情況,可以認為是長度為0的特殊邊。

/// 按步驟分解,碰撞檢測

public

bool

gjk(shape shapea,

shape shapeb)

******x.

add(p)

;// 單形體包含原點了

if(******x.

contains

(vector2.zero)

) direction =

findnextdirection()

;}computeclosetpoint()

;return

false

;}

選擇下次的迭代方向不同。上一章用的是原點到直線的垂線作為迭代方向;本章用的是原點到線段的最近向量,作為迭代方向。注意,原點到線段的最近距離不一定就是垂足,可能是線段的某個端點

不發生碰撞的結束條件不同。上一章迭代演算法最終結束時,可能是乙個不包含原點的三角形,為了得到差集最近邊,我們可以捨棄掉距離原點較遠的那個邊。這裡我們讓演算法多迭代一次,恰好可以捨棄掉那個點,同時會額外會產生乙個重複的support點。因此只要發現support點位置重疊了,就表明迭代演算法可以結束了。

計算步驟的分解**:

最近距離就是原點到差集最近邊的距離。先求出原點到線段的最近點,然後計算原點到最近點的距離即可。設線段為ab,原點為o,先計算出ao在ab上的投影長度:

這裡有個小技巧,計算投影長度,需要將被投影向量ab單位化,也就是要求ab的長度。但是為了讓ao在ab上投影長度單位化到[0, 1]之間,需要額外除以ab的長度,因此計算投影的時候,直接就除以ab長度的平方了,就省去了計算長度時的開方運算。

vector2

getclosestpointtoorigin

(vector2 a,

vector2 b)

// 計算投影長度,並單位化到[0, 1],需要額外除以ab的長度。因此這裡就直接除以長度的平方了。

float

projection = vector2.

dot(ab, ao)

/ sqrlength;

if(projection <0)

else

if(projection >

1.0f

)else

}

我們改造一下support方法,每次將生成support點用到的兩個頂點也記錄下來。這樣通過support點,可以反向找回多邊形的邊。

設是差集最近邊為l=a

bl = ab

l=ab

,a、b是support點,構成a、b兩的頂點分別自兩個多邊形的邊e1=

aa−b

ae1 = aa - ba

e1=aa−

ba、e 2=

ab−b

be2 = ab - bb

e2=ab−

bb。則求兩個凸包的最近距離,就演變成了求e1和e2兩個邊的最近距離。

設q是原點到l的垂直向量,也就是垂足,則有:

l = b - a \\ q · l = 0 \end

r2 = -(l · a) / (l · l)\\ r1 = 1 - r2 \\ qa = aa * r1 + ba * r2 \\ qb = ab * r1 + bb * r2 \end

⎩⎪⎪⎪⎨⎪

⎪⎪⎧​

r2=−

(l⋅a

)/(l

⋅l)r

1=1−

r2qa

=aa∗

r1+b

a∗r2

qb=a

b∗r1

+bb∗

r2​計算最近點的偽**如下:

void

computeclosetpoint()

else

}

gjk計算多邊形之間的最近距離,本質上是使用gjk演算法求得差集最近邊。而構成差集最近邊的兩個support點,就是來自兩個多邊形的最近邊上的4個頂點。然後就將問題轉換成,計算兩條邊之間的最近距離和最近點。

本章demo使用unity3d引擎開發,demo工程已上傳github:

nxOgre物理引擎

糾結半天還是來看了nxogre引擎。最後搭建的環境是 vs2010 nxogre ogre1.74 physx2.8.4 主要是看那個 betajaen s ramblings 這兩個算是比較新的了,其它的好像是ogre1.7版本以前的相容版本,沒法在新的ogre中使用了。最後乙個是教程,需要上面兩...

物理引擎ODE

出處 russell smith 的 open dynamics engine ode 是乙個開源的物理引擎,使用它可以 鉸接式固形體運動。這樣不管我們使用哪種圖形庫 可能使用 opengl 都可以對真實物件的物理特性進行 我們可以使用 ode 來對合成環境中的各種物件進行建模,例如三維遊戲環境中的...

APE物理引擎教程

ape 物理引擎有很好的效果,重要的是類很少,簡單易學。附件是我這個物理引擎寫的乙個遊戲,也是我的第乙個遊戲看到網上這個引擎的教程還比較少,當初找的好苦,發幾個我淘來的,下面幾個教程是在做遊戲過程中看的 ape物理引擎首頁 api文件 google論壇 有介紹貼圖,碰撞檢測 如何在flex中使用引擎...