1. 程式人生 > >GJK演算法求凸多邊形之間的距離

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

    GJK演算法最初用來求三維空間中凸多面體的距離(即最近距離),也因此經常用來做碰撞檢測(距離是否為0)。後被推廣到n維空間中求凸包之間的距離,此處用來求二維平面上2個凸多邊形的距離。
    GJK演算法首先要解決計算Minkowski和的問題。所謂Minkowski和,指A、B兩個集合,令A+B={x+y,其中x屬於A,y屬於B}即二者的Minkowski和。類似的可以定義負集與Minkowski差。
    若A、B為凸多邊形,頂點個數分別是n、m,則他們的Minkowski和一定是凸多邊形且至多有n+m個頂點。

aaaa

    左上為多邊形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個點,最後應該可能也許大概一定可以迭代到結果,只是影響迭代次數而已。
    上述GJK演算法來自《計算機圖形學幾何工具演算法詳解》中譯本,此書的某些演算法有問題,可能是翻譯的問題。
   用GJK演算法的Minkowski和可以解決POJ3608。凸多邊形的距離也可以使用旋轉卡殼法解決,但GJK演算法應該更容易實現一些。

相關推薦

GJK演算法多邊形之間距離

    GJK演算法最初用來求三維空間中凸多面體的距離(即最近距離),也因此經常用來做碰撞檢測(距離是否為0)。後被推廣到n維空間中求凸包之間的距離,此處用來求二維平面上2個凸多邊形的距離。     GJK演算法首先要解決計算Minkowski和的問題。所謂Minkowsk

一種多邊形內部似最大圓的算法

-s style 算法設計 alt 單純 思路 空間 nbsp 累加 文章版權由作者李曉暉和博客園共有,若轉載請於明顯處標明出處:http://www.cnblogs.com/naaoveGIS/ 1. 背景 任意多邊形內部一定有一個最大圓,但是如果

Python演算法----1-100之間的偶數和、奇數和

i = 1 sum1 = 0 sum2 = 0 while i <= 100: if i % 2 == 0: sum1 += i else: sum2 += i i +=1 print(“1-100之間偶數和為:%d” % sum1) print(“1-1

計算幾何 點到線段的距離 點在簡單多邊形內 點到多邊形距離

#include <bits/stdc++.h> using namespace std; struct point_t { double x,y; }; double cross(point_t const &O,point_t const &A,point_t con

Bridge Across Islands POJ - 3608 旋轉卡殼包最近距離

\(\color{#0066ff}{題目描述}\) 幾千年前,有一個小王國位於太平洋的中部。王國的領土由兩個分離的島嶼組成。由於洋流的衝擊,兩個島嶼的形狀都變成了凸多邊形。王國的國王想建立一座橋來連線這兩個島嶼。為了把成本降到最低,國王要求你,主教,找到兩個島嶼邊界之間最小的距離。 \(\color{

計算幾何工具演算法-任意多邊形的面積

題目描述: 給出n邊形的n個頂點座標,求這個n邊形的面積 題目分析: 如果在數學上,大概會把這個多邊形分成三角形(n-2)個三角形來求 但是這樣免不了繁瑣的演算法,程式設計複雜度和時間複雜度

【模板】Andrew演算法

凸包問題的一般解法有:Graham演算法、Melkman演算法、Andrew演算法等 Andrew演算法是Graham演算法的變種。 由於Andrew演算法程式碼簡便,效率比較高,筆者更推薦使用

poj 3525 多邊形的最大內切圓

【題意】 凸多邊形的最大內切圓 【題解】 二分+半平面交判定。 【程式碼】 #include <iostream> #include <cmath> #define eps 1e-8 #define oo 1e5 using namespace st

(hdu step 7.1.7)Wall(包的周長——將全部點圍起來的最小多邊形的周長)

esp minimal gree follow inpu clas foo sed sig 題目:WallTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot

Cows 計算幾何 多邊形面積

operator head opera -a ack ros mean lock rom 題目鏈接:https://cn.vjudge.net/problem/POJ-3348 題意 啊模版題啊 求凸包的面積,除50即可 思路 求凸包的面積,除50即可 提交過程 AC

多邊形最優三角剖分(演算法設計:動態規劃)

一、動態規劃       和分治法類似,把原問題劃分成若干個子問題,不同的是,分治法(子問題間互相獨立),動態規劃(子問題不獨立)       動態規劃: (1)找出最優解的性質,刻畫其結構特徵 (2)遞迴地定義最優值

HDU 1874 Dijkstra演算法 任意兩個點之間的最短距離

題意:          某省自從實行了很多年的暢通工程計劃後,終於修建了很多路。不過路多了也不好,每次要從一個城鎮到另一個城鎮時,都有許多種道路方案可以選擇,而某些方案要比另一些方案行走的距離要短很多。這讓行人很困擾。 #include&l

任意多邊形面積(凹多邊形多邊形

遇到問題:已知多邊形的各個左邊點,要求多邊形的面積 然後我搜索了下看到這篇文章:https://blog.csdn.net/tianyuhang123/article/details/56094559 這個人說的不多,但是簡單明瞭: 首先已知各定點的座標分別為(x1,y1),(x2,y2

計算幾何 平面最近點對 nlogn分治演算法 平面中距離最近的兩點

本文全文原創 轉載請註明出處 http://blog.csdn.net/lytning/article/details/25370169 平面最近點對,即平面中距離最近的兩點 分治演算法: int SOLVE(int left,int right)//求解點集中區間[lef

Graham's Scan演算法尋找離散點的多邊形(JavaScript版)

100個離散點的凸多邊形效果:  JavaScript程式碼實現如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></

判斷多邊形並排序演算法

在平面直角座標系中,給定一個點序列,判斷這些點是否能夠構成凸多邊形, 並且按照順時針方向輸出這些點。 其他要求: 1.輸出的起始的為距離原點最近的點,如果多點距離原點相等,取其中任一點即可; 2.如果有3個或者以上點在一條直線上,輸出"ERROR"; 輸入輸出格式要求:

poj3348(包的面積)graham演算法

Your friend to the south is interested in building fences and turning plowshares into swords. In order to help with his overseas adventure, they are force

C語言經典演算法1-100之間素數

#include<stdio.h> #include<stdlib.h> #include<assert.h> #include<math.h> in

平面多邊形和空間包絡體演算法整理

最近畢設專案中用到了最大包絡體求算演算法,在這裡進行簡單的整理,為了以後更好的理解。 準備知識 關於點的定義 //空間上任何一個點資訊 struct Point { double x, y, z; Point(){} Point(double xx,do

地理座標轉3度或6度分帶的演算法以及任意多邊形面積的方法(與Arcmap相差0.81%)

一:首先補充下理論知識(網上找的) 對於不同的橢球體之間的轉換要用到七引數的方法,這個不還沒有研究。本文不是講的這個。 因為本文章主講演算法,理論知識就不多說了。 分帶方法 1.我國採用6度分帶和3度分帶:             1∶2.5萬及1∶5萬的地形圖採用6度分帶投影,即經差為6度,從零度