1. 程式人生 > >淺談凸包及Graham掃描法

淺談凸包及Graham掃描法

    凸包是計算幾何中的一個基本概念。在競賽中,很少單獨考察凸包,但求凸包是很多題目求解的一個關鍵性步驟。

    1)凸包的性質

        給定一個點集,凸包是能夠包圍所有點的最小凸多邊形。”凸包邊上的點,稱為凸包點,其餘點稱為凸包內點“(引自何援軍著《幾何計算》)

        凸包有一些區別於普通多邊形的重要性質:

        1.所有的頂點均在任何一條凸包邊所在直線的一側,如果逆時針遍歷凸包的邊,則對每條邊,所有點均在其左側。

        2.從任一點出發,沿逆時針遍歷凸包,總是向左轉,沿順時針遍歷凸包,總是向右轉(即叉乘的符號在沿同一方向運動時是不變的)。

        3.凸包對凸包點排序,即選定一條邊,凸包上的點依次與該邊所在直線的距離成單峰函式。

    2)凸包求法

        經常會遇到這樣的問題:給定平面上的一些點,求這些點對應的凸包。

        此處暫介紹一種方法:Graham掃描法,還有其他方法,這裡不再介紹。

        步驟如下:

        1.將點按照x座標排序,x座標相同就按y座標排序。

        2.第一個點必定是凸包中的點,將其壓入棧S中。

        3.對下一個點進行判斷,如果棧內元素小於2個,則將該點直接加入棧中;否則,進行叉積判斷。如果是進行逆時針判斷,只要遇到向右轉的情況,就從棧中彈出一個點,直到棧中只剩一個點或者出現左轉。重複此步驟,直到n個點全部遍歷完畢。

        4.從n開始,向前遍歷,遍歷方法如3,直到遍歷到第一個點。

        整體過程如下圖所示:

       

這時遇到右轉,將P3彈出。

再次遇到右轉情況,彈出P4。

特別提醒:如果出現三點共線的情況,最好將中間的點刪去,可以讓複雜度稍微小一點。

出現右轉,將P5彈出。

右轉,彈出P4。

回到起點,這時棧S中的元素:P1,P2,P5,P6,P3,P1,這就是整個凸包的凸包點的集合。

程式碼實現如下:

point s[N];                                      //執行結束時,凸包點按順序存於s中,n為凸包頂點的個數 
double cp(point a,point b,point o)               //叉積 
{
	return (a-o)*(b-o);
}
void convex(point *p,int &n)                     //引數p為輸入點,n為輸入點個數 
{
	sort(p,p+n);                                 //將點按x座標排序,如果x相同按y座標排序 
	int i,j,r,top,m;
	s[0]=p[0];s[1]=p[1];top=1;
	for(i=2;i<n;++i)                             //從前向後掃描 
	{
		while(top>0&&cp(p[i],s[top],s[top-1])>=0)
		  top--;
		top++;s[top]=p[i];
	}
	m=top;                                       //記錄當前棧s裡元素的個數 
	top++;s[top]=p[n-2];
	for(i=n-3;i>=0;i--)                          //從後向前掃描 
	{
		while(top>m&&cp(p[i],s[top],s[top-1])>=0)
		  top--;
		top++;s[top]=p[i];
	}
	top--;
	m=top+1;
}

【習題推薦】

HDU 3629

HDU 1348

相關推薦

Graham掃描

    凸包是計算幾何中的一個基本概念。在競賽中,很少單獨考察凸包,但求凸包是很多題目求解的一個關鍵性步驟。     1)凸包的性質         給定一個點集,凸包是能夠包圍所有點的最小凸多邊形。”凸包邊上的點,稱為凸包點,其餘點稱為凸包內點“(引自何援軍著《幾何計算

尋找Graham掃描

題意描述: 對任意給定的平面上的點集,求最小凸多邊形使得點集中的點要麼在凸多邊形的邊上,要麼在凸多邊形的內部。 Graham演算法描述: 在所有的點中找到一點p0,使得p0的縱座標值最小,在有多個最小縱座標的情況下,找橫座標最小的那一個。 將所有的點

matlab練習程式(尋找Graham掃描

  我不太清楚這個凸包在影象處理中到底會怎樣的運用,因為這個好像更多的是計算幾何或是圖形學裡面的東西。不過作為一個演算法,我感覺還是有必要研究一下的。我主要的參考資料是《演算法導論》的33.3和這個部落格。   程式碼在這裡,我只寫了主要過程,過分細節的判斷就省略了。這裡是逆時針尋找: main.m c

問題—Graham掃描

#include<iostream> #include<cmath> #include<algorithm> using namespace std; struct point { long long x; long l

之Andrew 與 Graham

前言 腦補知識點: 1.向量的內積(數量積,點乘): 公式:a· b = |a| * |b| cos<a, b>=a.x* b.y + b.x * a.y 2.向量的外積(向量積,差乘): 公式:|c|= |a|*|b|*sin<a, b> = a

1015 - 計算幾何之Graham掃描 - Cows(POJ 3348)

傳送門   題意 給你一堆點,求這些點的凸包,並求出面積   分析 很久之前就做過的一道題了,還記得那是凱爺(凱爺好厲害好厲害的)講的,是Jarris步進法:按照橫縱座標對所有的點進行排序(橫座標優先) 然後就是和Graham類似的方法了,邊掃描邊

演算法(Graham掃描

目錄 一、概念 二、演算法步驟 三、程式碼實現 轉自:https://www.cnblogs.com/aiguona/p/7232243.html 一、概念 凸包(Convex Hull)是一個計算幾何(圖形學)中的概念。 在一個實數向量空間V中,對於給定集合X,所有

最小演算法(Convex Hull)(1)-Graham掃描 -計算幾何-演算法導論

基本問題: 平面上有n個點p1,p2, ..., pn, 要求求出一個面積最小的凸多邊形,使得這個多邊形包含所有平面上的點。 根據演算法導論上提供的兩個方法做一些介紹: 演算法1: Graham掃描法 下面直接給出一段虛擬碼,方便描述: GRAHAM-SCAN(Q) {

計算幾何之----Graham掃描

計算幾何之凸包(convexHull)----Graham掃描法 關於凸包的嚴格定義,這裡不打算寫出來,大家可以自行Google或者百度,因為嚴格的數學定義反而不太好理解,用最通俗的話來解釋凸包:給定

模板(分治 or Graham掃描

問題概述:空間上有很多點,現在要用一個凸多邊形將所有點全部包住,求哪些點在這個凸多邊形上 輸入樣例:                                             對應輸出:

--Graham掃描

一直聽大佬們說:凸包、凸包、凸包 一直不會。。。。。 然後。。。。 今天考試,考了一道計算幾何的簡單題。。。。 這,,,還是學一下吧。。 然後考試現場學習一下凸包演算法。 先理解一下凸包是啥東西。 看看這張圖 解釋一下凸包是什麼 如果你有一堆點(原諒我畫的很凌亂) 那麼,找到一個點集 依次連線這些點 使他們

演算法詳解-Graham掃描

#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; struct nod

關於——Graham掃描

首先是凸包的第一種解法,graham掃描法。演算法的步驟如下: 1 首先我們要找到凸包的一個頂點,這個頂點的y座標要最小,相同的y的情況下,選擇更靠左的點 2 對給出的頂點集進行排序,按照極角遞增的順序進行排序?如何進行操作呢,我們可以用我們向量積的性質,如果向量積為正,b

(Convex Hull)構造演算法——Graham掃描

凸包(Convex Hull) 在圖形學中,凸包是一個非常重要的概念。簡明的說,在平面中給出N個點,找出一個由其中某些點作為頂點組成的凸多邊形,恰好能圍住所有的N個點。 這十分像是在一塊木板上釘了N個釘子,然後用一根繃緊的橡皮筋它們都圈起來,這根橡皮筋的形狀就是所謂的凸包。 計算凸包的一個著名演

-Andrew演算法&&Graham掃描

凸包簡介: 在二維平面上(二維凸包)給出若干個點,能夠包含這若干個點的面積最小的凸多邊形稱為凸包(可以想像有很多個釘子釘在牆上,然後用一個橡皮圈套在所有的釘子上,最後橡皮圈形成的就是一個凸包)。 Graham掃描法: Graham掃描法是一種基於極角排序的進行求解的

計算幾何 : 學習筆記 --- Graham 掃描

 凸包 (只針對二維平面內的凸包) 一、定義 簡單的說,在一個二維平面內有n個點的集合S,現在要你選擇一個點集C,C中的點構成一個凸多邊形G,使得S集合的所有點要麼在G內,要麼在G上,並且保證這個凸多邊

Graham掃描->HDU3847

Graham掃描法求凸包 凸包定義: 點集Q的凸包(convex hull)是指一個最小凸多邊形,滿足Q中的點或者在多邊形邊上或者在其內。 凸包最常用的凸包演算法是Graham掃描法和Jarvis步進法。 Graham掃描法: 首先

二維求 graham掃描

graham掃描法求凸包的做法就是,選擇一個座標最靠近左下的點,然後作為原點,其他點按極座標排序,角度由小到大,角度想等r小的優先,然後將前兩個點放到棧中進行初始化,之後順序對每一個點進行判斷,只有該點向左發生了偏轉才將該點入棧,否則刪掉當前棧頂元素,再次判斷,直到發生了向

計算機領域職業憧憬

計算機科學 軟件工程師 計算機行業 雖然自己的專業是計算機,可是慚愧的說其實對這個行業的了解並不是很多,大多時候是通過網絡或者新聞才了解到的。據我所知,現在計算機行業是非常流行的行業,當然競爭也是十分激烈,信息化的時代我們的生活都離不開與計算機有關的東西,比如上學坐公共汽車,需要刷卡,這就是

trie樹 事實上現

空間換時間 字符串 arc com post pre 1.5 dsm back 定義:又稱字典樹,單詞查找樹或者前綴樹,是一種用於高速檢索的多叉樹結構。 如英文字母的字典樹是一個26叉樹,數字的字典樹是一個10叉樹。 核心思想:是空間換時間.利用字符串的公共前綴來