凸包

点集Q的凸包是一个最小的凸多边形P,满足Q中的每个点或者在P的边界上,或者在P的内部。

主要介绍Graham扫描算法,时间复杂度为O(nlgn)。

算法:通过设置一个关于候选点的堆栈S来解决凸包问题。输入集合Q中的每个点都压入栈一次,非CH(Q)中顶点的点最终被弹出堆栈。当算法终止时,堆栈

S中仅包含CH(Q)中的顶点,其顺序为各点在边界上出现的逆时针方向排序的顺序。

Graham_Scan(Q):

int Graham()
{
    int i, top, tmp = 0;
    for(i = 1; i < n; i++)
        if((map[i].y<map[tmp].y) || (map[i].y == map[tmp].y && map[i].x < map[tmp].x))
            tmp = i;
    Point p = map[tmp];
    map[tmp] = map[0];
    map[0] = p;
    sort(map + 1, map + n, cmp);
    S[0] = map[0];
    S[1] = map[1];
    S[2] = map[2];
    top = 2;
    for(i = 3; i < n; i++)
    {
        while(direction(S[top - 1],map[i],S[top]) > 0)
            top--;
        S[++top] = map[i];
    }
    return top;
}

int direction(Point p0, Point p1, Point p2)
{
    return (p1.x - p0.x)*(p2.y - p0.y) - (p2.x - p0.x)*(p1.y - p0.y);
}

int cmp(Point p1, Point p2)
{
    if(direction(map[0],p1,p2) > 0)
        return 1;
    else if(direction(map[0],p1,p2) == 0 && (dist(map[0],p1)-dist(map[0],p2) < 0))
        return 1;
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值