GJK算法計算凸多邊形之間的距離

GJK是空間距離檢測算法,是由三位(Gilbert, Johnson, and Keerthi's ) 作者的首字母組成的代稱。  

GJK算法首先要解決計算Minkowski和的問題。所謂Minkowski和,指A、B兩個集合,

令A+B={x+y,其中x屬於A,y屬於B}即二者的Minkowski和。類似的可以定義負集與Minkowski差。

 若A、B爲凸多邊形,頂點個數分別是n、m,則他們的Minkowski和一定是凸多邊形且至多有n+m個頂點。

 

左上爲多邊形A、B,假設黑點爲原點,三個圖分別表示-B、A+B與A-B。A、B之間的點對距離即||x - y||,其中x屬於A,y屬於B;而A、B之間的距離就是||x-y||的最小值。因此,A、B之間的距離就是其Minkowski差A-B中的最小元素,這個最小指的是模最小,實際上就是距離原點的距離。因此,2個凸多邊形的距離轉化爲點到凸多邊形的距離,點指的是原點,凸多邊形指的是原題中的2個凸包的Minkowski差。

    Minkowski和的算法如下,將A、B的邊按逆時針方向拆成向量(順時針實際上也可以),如上圖可以得到6個向量。將這些向量按極角排序,然後依次首尾相連即可得到凸包。

    上述算法只是得到了和的形狀與相對位置(因爲首尾相連時出發的基點是原點),實際上該凸包還需做一個平移才能得到正確的座標。如果排序時極角是取0~360度範圍(NOTE:不必顯式的求出極角,用先象限後叉積的方法排序),則求出A、B各自的最下最左點,將其座標相加作爲出發的基點即可。代碼實現上這一點其實非常容易完成。

    求出Minkowski差之後(求差與求和本質是一樣的),剩下的就是求點到凸多邊形的距離,這個問題又轉化爲求點到邊的距離。一個凸多邊形有n條邊,點到這n條邊的距離的最小值就是點到凸多邊形的距離。而且,點到邊的距離是具有確定單調性的,因此運氣好的話不需要求出所有邊的距離,只需掃描到極小值即可。點到邊的距離也就是點到線段的距離,利用叉積計算、點積進行判斷,很容易求得。

    上述算法其實不是GJK算法,因爲所求爲凸多邊形,而GJK算法可以用來求曲線凸包之間的距離(此情況下是一個數值逼近過程)。簡單描述一下GJK的迭代過程,除了初始情況下,每一步迭代時均已求得凸包邊緣上的3個點構成一個三角形Tk,然後求指定點p距離Tk最近的點,記作q,再將凸包投影到pq。qp方向上最遠的投影點所對應的凸包上的點記作w,最後將Tk的3個點捨去1個,然後加上w形成新的Tk+1。最開始的3個點哪裏來的?似乎可以隨便選邊緣上的3個點,最後應該可能也許大概一定可以迭代到結果,只是影響迭代次數而已。

Java版本代碼片段

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章