凸包入門知識

2021-07-15 15:25:58 字數 2275 閱讀 8426

平面凸包 :

定義:對乙個簡單多邊形來說,如果給定其邊界上或內部的任意兩個點,連線這兩個點的線段上的所有點都被包含在該多邊形的邊界上或內部的話,則該多邊形為凸多邊形 。

在解決平面凸包下面介紹了兩種演算法:

一、 

graham

掃瞄法,執行時間為o(nlgn)。

二、  jarvis步進法,執行時間為o(nh),h為凸包中的頂點數。

graham掃瞄法

基本思想:通過設定乙個關於候選點的堆疊s來解決凸包問題。

操作:輸入集合q中的每乙個點都被壓入棧一次,非ch(q)(表示q的凸包)中的頂點的點最終將被彈出堆疊,當演算法終止時,堆疊s中僅包含ch(q)中的頂點,其順序為個各頂點在邊界上出現的逆時針方向排列的順序。

注:下列過程要求|q|>=3,它呼叫函式top(s)返回處於堆疊s 頂部的點,並呼叫函式next-to –top(s)返回處於堆疊頂部下面的那個點。但不改變堆疊的結構。

graham-scan(q)

1          

設p0 是q 中y 座標最小的點,如果有多個這樣的點則取最左邊的點作為p0;

2          

設是q 中剩餘的點,對其按逆時針方向相對p0 的極角進行排序,如果有數個點有相同的極角,則去掉其餘的點,只留下乙個與p0 距離最遠的那個點;

3          

push(p0 , s)

4          

push(p1 , s)

5          

push(p3 , s)

6          

for i ←3 to m

7          

do while 由點next-top-top(s),top(s)和pi 所形成的角形成一次非左轉

8          

do pop(s)

9          

push(pi , s)

10       

return s

首先,找乙個凸包上的點,把這個點放到第乙個點的位置p

0。然後把p1~pm 按照p0pi的方向排序,

可以用向量積(叉積)判定。

做好了預處理後開始對堆疊中的點中的每乙個點進行迭代,在第7到8行的while迴圈把發現不是凸包中的頂點的點從堆疊中移去。(原理:沿逆時針方向通過凸包時,在每個頂點處應該向左轉。因此,while迴圈每次發現在乙個頂點處沒有向左轉時,就把該頂點從堆疊中彈出。)當演算法向點pi推進、在已經彈出所有非左轉的頂點後,就把pi壓入堆疊中。

舉例如下:

最少附上乙份凸包的模板

#include#include#include#includeusing namespace std;

const int maxn=1010;

const double pi=acos(-1.0);

struct point

;point list[maxn];

int stack[maxn],top;

double cross(point p0,point p1,point p2) //計算叉積 p0p1 x p0p2

double dis(point p1,point p2) //計算 p1p2的 距離

bool cmp(point p1,point p2) //極角排序函式 , 角度相同則距離小的在前面

}list[k]=list[0];

list[0]=p0;

sort(list+1,list+n,cmp);

}void graham(int n)//graham掃瞄法

if(n==2)

if(n>2)}}

凸包知識介紹

給定二維平面上的一堆點中,凸包就是將最外層的點連線起來構成的凸多邊形,它能包含點集中所有的點。如上圖所示,點集中外層的點構成的凸多邊形就構成了能夠包含所有點的凸包,其中連線相鄰頂點構成的邊越來越平緩,或者說斜率越來越小構成的一組點叫做上凸殼,而相鄰的邊,斜率越來越大的一組點叫做下凸殼。關於斜率,同學...

圈水池(凸包入門)

描述 有乙個牧場,牧場上有很多個供水裝置,現在牧場的主人想要用籬笆把這些供水裝置圈起來,以防止不是自己的牲畜來喝水,各個水池都標有各自的座標,現在要你寫乙個程式利用最短的籬笆將這些供水裝置圈起來!籬笆足夠多,並且長度可變 輸入 第一行輸入的是n,代表用n組測試資料 1 n 10 第二行輸入的是m,代...

圈水池 凸包入門

時間限制 3000 ms 記憶體限制 65535 kb 難度 4 描述 有乙個牧場,牧場上有很多個供水裝置,現在牧場的主人想要用籬笆把這些供水裝置圈起來,以防止不是自己的牲畜來喝水,各個水池都標有各自的座標,現在要你寫乙個程式利用最短的籬笆將這些供水裝置圈起來!籬笆足夠多,並且長度可變 輸入第一行輸...