問題
設p1=(x1,y1),p2=(x2,y2),...,pn=(xn,yn)是平面上n個點構成的集合s,凸包問題是為集合s構造最小凸多邊形。
思路設p1=(x1,y1),p2=(x2,y2),...,pn=(xn,yn)按照x軸座標公升序排列,則最左邊的點p1和最右邊的點p2一定是該集合的凸包頂點。如圖1所示。設p1pn是經過點p1和pn的直線,這條直線把集合s分成兩個子集:s1是位於直線上側和直線上的點構成的集合,s2是位於直線下側和直線上的點構成的集合。s1的凸包由下列線段構成:以p1和pn為端點的線段構成的下邊界,以及由多條線段構成的上邊界,這條上邊界成為上包。類似地,s2中的多條線段構成的下邊界稱為下包。整個集合s的凸包是由上包和下包構成的。
下面討論如何求解上下包。對於集合s1,s1中所有直線p1pm上側的點構成集合s11,s1中所有在直線pmpn上側的點構成集合s12,包含在三角形pmp1pn之中的點可以不考慮了。遞迴地繼續構造集合s11的上包和集合s12的上包,然後將求解過程中得到的所有最遠距離的點連線起來,就可以得到集合s1的上包。同理,可求得集合s2的下包。如圖2所示
圖1 點集合s的上包和下包 圖2 遞迴地求集合s1的上包
c++實現
/*
程式:分治法解決凸包問題
*/ #include#include#include#include#include#includeusing namespace std;
struct point;
inline bool compx(const point &p1, const point &p2)
/* 函式:求點p在以p1和p2決定直線的上側還是下側
返回值:上側:>0 下側:<0 在直線上:=0
*/inline double line(const point &p1, const point &p2, const point &p)
/* 函式:求點p到以p1和p2決定直線的距離
*/double dist(const point &p1, const point &p2, const point &p) /*
函式:求解直線p1p2上點集的上包
引數:v:直線p1p2上的點集 vo:上包點集
*/void uphull(const vector&v, vector&vo, const point &p1,const point &p2)
double d = 0;
int k;
for(int i = 0; i < v.size(); ++i)
} vo.push_back(v[k]);
vectorvl;
vectorvr;
for(int i = 0; i < v.size(); ++i)
uphull(vl,vo,p1,v[k]);
uphull(vr,vo,v[k],p2);}/*
函式:求解直線p1p2下點集的下包
引數:v:直線p1p2下的點集 vo:下包點集
*/void downhull(const vector&v, vector&vo, const point &p1,const point &p2)
double d = 0;
int k;
for(int i = 0; i < v.size(); ++i)
} vo.push_back(v[k]);
vectorvl;
vectorvr;
for(int i = 0; i < v.size(); ++i)
downhull(vl,vo,p1,v[k]);
downhull(vr,vo,v[k],p2);}/*
函式:求解點集v的凸包
*/ void convexhull(vector&v, vector&vo)
uphull(vu,vo,v[0],v[v.size()-1]);
downhull(vd,vo,v[0],v[v.size()-1]);
}int main()
vectorvo;
convexhull(v,vo);
for(auto p : vo)
cout << "" << endl;
return 0;
}
箴言錄:
夫君子之行,靜以修身,儉以養德,非淡泊無以明志,非寧靜無以致遠。
分治法 凸包問題
什麼是凸包?我的理解就是,圖形任意兩點的連線都沒有在圖形外部。問題 給定點集,怎麼求出凸包的邊界點呢?第一步 給這些點按照x的從大到小進行排序,如果x相同的按照y再排序。第二步 把x最小的和最大的連起來,他們必為凸包的邊界點。第三步 把平面區域分為兩個部分,分別在上面和下面去找面積最大的三角形 面積...
凸包問題之分治法
凸包 按橫座標排序,以最小點與最大點之間的連線為準,在直線一側找使三角形面積最大的點,此點必在凸包內,以找到點與最大點或最小點繼續遞迴以尋找最大三角形面積尋找凸包點,直至找不到符合條件的點。實現 如下 include include include define max size 10001 str...
凸包問題 (用分治演算法)
問題描述 在平面上有n個點,其中任何三個點都不在一條直線上,問如何尋找乙個點集,使得這些點構成的多邊形剛好能把所有點都包進。基本思想 我們採用分治演算法。首先算出這n個點的橫座標中位數,記為x0,畫出直線x x0,將整個平面分成兩部分。我們要做的就是分別求兩部分的凸包,最後再合併即可。利用分治和遞迴...