二維幾何-凸包

顧名思義,凸包就是把給定點包圍在內部的、面積最小的凸多邊形,它在計算幾何中有着及其重要的作用。

這裏介紹一下Andrew算法。

算法思想:首先把所有點按照x從小到大排序(如果x相同,按照y從小到大排序),刪除重複點後得到序列p1,p2....然後把p1和p2放到凸包中。從p3開始,當新點在凸包前進方向的左邊時繼續,否則依次刪除最近加入凸包的點,直到新點在左邊。重複這個過程,直到碰到最右邊的pn,就求出了下凸包,然後反過來從pn開始再做一次,求出上凸包,合併起來就是完整的凸包。

這個算法在排序後僅僅是從左到右和從右到左各掃描了一次,時間複雜度爲O(n)。加上排序後時間複雜度也僅爲O(nlogn).

算法實現:

計算凸包,輸入點數組p,個數爲n,輸出點數組ch。函數返回凸包頂點數。

函數執行完後輸入點的順序被破壞

如果不希望在凸包的邊上有輸入點,把兩個<= 改成 <

在精度要求高的時建議用dcmp比較。

int ConvexHull(Point *p, int n, Point *ch)
{
    int i, k, m;

    sort(p, p+n);                                                   //先比較x座標,再比較y座標
    n = unique(p, p+n) - p;                                         //去除重複點
    m = 0;
    for(i = 0; i < n; i++)
    {
        while(m>1 && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0)     //至少有倆點,才能刪點
            m--;
        ch[m++] = p[i];
    }
    k = m;
    for(i = n-2; i >= 0; i--)
    {
        while(m>k && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0)
            m--;
        ch[m++] = p[i];
    }

    if(n > 1)                                                       //如果n大於1,則最後數組中有兩個p[0] 需要減少一個 n=1則不需要。
        m--;

    return m;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章