學習筆記 凸包

2022-06-02 02:54:13 字數 2939 閱讀 6654

想學斜率優化,先把先決條件凸包給肝了。然後完全不懂,於是就咕了。順便看了一下線代(其實並不會)

講真這東西耗了我半個暑假

20210305更新:po學了向量回來了發現這寫的什麼玩意,已更新完畢,您可從更新部分跳至凸包部分。同時,原「前置知識:叉積」部分已棄用並放置於最後。

目錄更新

以下內容大部分在人教a版數學必修2第一章中涉及。

向量是什麼,你可以不必知道,只需知道其有兩個要素:方向和大小,它可以用有向線段表示。下文中我們將寫作\(\vec\)或\(\vec\)

我們先解釋一下向量的座標:將這條有向線段的起點置於 \((0,0)\),則該線段的終點座標即為該向量的座標。

再解釋一下向量的共線判定,用數乘表示則是:對於向量\(\vec\),\(\vec\),存在乙個實數\(\lambda\),使得\(\lambda \vec = \vec\)。而引入座標後,設\(\vec\)座標為\((a_x,a_y)\),\(\vec\)座標為\((b_x,b_y)\),則若兩向量共線,則有

\(\huge a_x b_y-a_y b_x=0\)

這個形式便是叉積。類似的,通過畫圖,我們可以得出\(\vec\)和\(\vec\)的關係 對應 叉積與零的關係。(注:我們定義若乙個向量\(\vec\),能通過順時針旋轉小於\(\frac\)與\(\vec\)所在的直線重合,則\(\vec\)在\(\vec\)的右邊。反之同理。)

先給出結論,若\(\vec\)

\(\vec\)叉積小於零,則\(\vec\)在\(\vec\)的左邊。

需要注意的是,下文中,我們的原點不一定是\((0,0)\),而可能是其他點。而對應的,座標也並非相對於\((0,0)\),而是我們定義的,會改變的「原點」。一般的,按照下圖的情況,我們將會定義原點為\(p\)。

凸包初講

我們定義,在平面上能包含所有給定點的最小凸多邊形叫做凸包。凸包的周長最小。

簡單的說,平面上有一些點,你要用乙個凸多邊形把它們圍起來。並且這個多邊形最小。

**實現

這裡介紹一種實現凸包的演算法。

首先我們可以將所有點按照其\(x\)座標和\(y\)座標做雙關鍵字排序。然後我們分別維護上凸殼和下凸殼,維護凸殼我們用單調棧實現。顯然第乙個點和最末點一定在凸包上,所以我們可以從前往後找可以維護上凸殼,從後往前找可以維護下凸殼。

根據凸多邊形的定義,若點\(y\)在點\(x\)的右邊,則線段\(xy\)則一定不在凸包上

根據這個原理,我們在單調棧維護點時,若找到這種不凸的點,則將其彈出。直到凸了才將點入棧。要注意的是,判斷凸不凸至少需要3個點,即棧中至少要有2個點

以上面圖為例,我們首先將\(a\)和\(p\)入棧,到\(b\)時,發現\(\vec\)與\(\vec\)的叉積大於0,即\(b\)在\(a\)點右邊,這顯然不合法,於是將\(p\)彈出,此時棧中僅有\(a\)乙個點,將\(b\)入棧。

對於共線的情況,可以靈活處理。

當我們正著做一遍,倒著做一遍,凸包就求出來了。

例題本題顯然求的是凸包的周長

例題**

#includeusing namespace std;

double ans;

int n,q[10100];

struct point

p[10100];

bool cmp(point x,point y)

//叉積

double len(point x,point y)

//長度計算

int main()

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

//*****上凸殼====

int h=0,t=1;

q[1]=1;

for (int i=2;i<=n;i++)

q[++t]=i;

} //===下凸殼====

h=t-1;

for (int i=n-1;i>0;i--)

{ while (h+1分割線

以下為棄用部分。

前置知識:叉積

這個屬於線性代數,有興趣的請上b站學習。推薦鏈結

下文中將使用\(*\)代指乘,用\(\times\)代指叉積

根據某些線代知識,叉積在幾何意義上代表的是以\(a\),\(b\)兩個向量為兩條邊的平行四邊形的面積。

而叉積的運算公式(簡略版)為

\(\huge a.x*b.y-a.y*b.x\)

注意,這裡的\(x\),\(y\),都是相對於某一點而言的。例如,下圖的\(x\)與\(y\)相對於點\(p\)而言,而不是相對於點\(o\)而言。

求出叉積後,我們可以借助其來判斷兩個點的相對位置

我們定義若乙個向量\(x\),能通過順時針旋轉小於\(180\)度角與\(y\)所在的直線重合,則\(y\)在\(x\)的右邊。反之同理。則叉積與方向的關係為

若\(a \times b >0\)則\(b\)在\(a\)的右邊

若\(a \times b <0\)則\(b\)在\(a\)的左邊

若\(a \times b =0\)則兩點共線

凸包學習筆記

凸包 凸包 convex hull 是乙個計算幾何 圖形學 中的概念。在乙個實數向量空間v中,對於給定集合x,所有包含x的凸集的交集s被稱為x的凸包。x的凸包可以用x內所有點 x1,xn 的線性組合來構造.在二維歐幾里得空間中,凸包可想象為一條剛好包著所有點的橡皮圈。用不嚴謹的話來講,給定二維平面上...

平面凸包 學習筆記

什麼是平面凸包?平面凸包 以下簡稱 凸包 是指覆蓋平面上n個點的最小凸多邊形。形象來說就是把n個點看成n根柱子,用橡皮筋去緊框住這n根柱子,最後形成的拉緊的多邊形就是要求的凸包。怎麼求平面凸包?1.jarvis演算法 首先我們需要了解凸包的數學構造法 找一條直線l過其中一點 記為a 並且其他所有點都...

OpenCV學習筆記(十五)之凸包

老規矩 妹妹鎮樓 輸入候選點,來自findcontours outputarray hull,凸包 bool clockwise,順時針方向 bool returnpoints,true表示返回點個數,如果第二個引數是vector則自動忽略 首先把影象從rgb轉為灰度影象 轉為二值影象 通過發現輪廓...