二维几何-凸包

顾名思义,凸包就是把给定点包围在内部的、面积最小的凸多边形,它在计算几何中有着及其重要的作用。

这里介绍一下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;
}

 

    原文作者:算法
    原文地址: https://www.twblogs.net/a/5bd3a0592b717778ac209be9
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞