求凸包—— graham_scan算法

求凸包—— graham_scan算法

先按Y-X排序,在按对p0的极角排序,然后进行扫瞄

bool cmp(Point A,Point B)

{

    //return (A-vert[0])*(B-vert[0])>EPS;

    double tmp=(A-vert[0])*(B-vert[0]);

    if(tmp>EPS) return true;

    if(fabs(tmp)<EPS) return dist(A,vert[0])>dist(B,vert[0])+EPS;///极角相同时,距离远的在前

    return false;

}



bool cmpYX(Point A,Point B)

{

    if(A.y<B.y-EPS) return true;

    if(A.y==B.y) return A.x<B.x-EPS;

    return false;

}



void graham_scan()

{

    sort(vert,vert+N,cmpYX);

    sort(vert+1,vert+N,cmp);

    top=0;

    con[top++]=vert[0];

    con[top++]=vert[1];

    for(int i=2;i<=N;i++){

        if((con[top-1]-con[top-2])*(vert[i%N]-con[top-1])<-EPS){

            top--;

            con[top++]=vert[i%N];

        }

        else if(fabs((con[top-1]-con[top-2])*(vert[i%N]-con[top-1]))<EPS){///拐向相同时,取距离远的,舍弃距离近的

            if(dist(vert[i%N],con[top-2])>dist(con[top-1],con[top-2])+EPS){

                top--;

                con[top++]=vert[i%N];

            }

        }

        else con[top++]=vert[i%N];

        while(top>=3&&(con[top-2]-con[top-3])*(con[top-1]-con[top-2])<EPS){///这步处理是必要的

            Point tmp=con[top-1];

            top-=2;

            con[top++]=tmp;

        }

    }

}
View Code

 

你可能感兴趣的:(算法)