把点集凸包化Granham-Scan算法(使用水平序)概要

  • 格式:doc
  • 大小:101.00 KB
  • 文档页数:7

下载文档原格式

  / 7
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

把点集凸包化Granham-Scan算法(使用水平序)

#include

#include

#include

#include

using nameaace std;

const int M=100000+5;

struct Point

{

double x,y;

} p[M];

double dis(Point A,Point B)

{

return sqrt((B.x-A.x)*(B.x-A.x)+(B.y-A.y)*(B.y-A.y));

}

bool cmp(Point a,Point b)

{

if (a.x

if (a.x>b.x) return false;

if (a.y

return false;

}

double Xdet(Point A,Point B,Point C)

{

double x1,x2,y1,y2;

x1=B.x-A.x; y1=B.y-A.y; x2=C.x-A.x; y2=C.y-A.y;

return x1*y2-x2*y1; //大于0在左手边,逆时针

}

bool bo[M];

Point pp[M];

int stack[M]; //from 1 to t

void Gram_Scan(Point *p,int &n) //p从1-n,把点集土包化 n*log(n); {

int i,t;

sort(p+1,p+1+n,cmp);

for(t=0,i=1;i<=n;i++){ //合并排序

if (i>1 && p[i].x==p[i-1].x && p[i].y==p[i-1].y) continue;

p[++t]=p[i];

}

n=t; t=0;

memset(bo+1,true,n*sizeof(bo[0]));

if (n>0){

stack[++t]=1;

bo[stack[t]]=false;

}

if (n>1){

stack[++t]=2;

bo[stack[t]]=false;

}

if (n>2){

for(i=3;i

if(bo[i] && Xdet(p[stack[t-1]],p[stack[t]],p[i])>=0) stack[++t]=i,bo[i]=false;

else{

while(t>=2&& Xdet(p[stack[t-1]],p[stack[t]],p[i])<0) bo[stack[t]]=true,t--;

stack[++t]=i;

bo[stack[t]]=false;

}

for(i=n;i>=1;i--)

if (bo[i] && Xdet(p[stack[t-1]],p[stack[t]],p[i])>=0) stack[++t]=i,bo[i]=false;

else{

while(t>=2&&Xdet(p[stack[t-1]],p[stack[t]],p[i])<0) bo[stack[t]]=true,t--;

stack[++t]=i;

bo[stack[t]]=false;

}

t--;

}

for(i=1;i<=t;i++) pp[i]=p[stack[i]];

memcpy(p+1,pp+1,t*sizeof(Point));

n=t;

}

求凸点集的面积

double area(Point *p,int n)

{

double sum=0;

int i;

p[n+1]=p[1];

for(i=1;i<=n;i++)

sum+=p[i].x*p[i+1].y-p[i].y*p[i+1].x;

return sum/2.0;

}

const double EPS=1e-9;

const double maxn=1e6-1;

const double PI=acos(-1.);

const int M=100+5;

const double offset=11213;

#define zero(x) (((x)>0?(x):-(x))

struct Point{

double x,y;

} p[M];

struct LINESEG{

Point st,ed;

};

struct LINE{

double a,b,c;

};

double dist(Point a,Point b){

return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));

}

double multiply(Point a,Point b,Point c){

return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);

}

double dotmultiply(Point a,Point b,Point c){

return (a.x-c.x)*(b.x-c.x)+(a.y-c.y)*(b.y-c.y);

}

bool online(LINESEG L,Point q){

return fabs(multiply(L.ed,q,L.st))

LINE makeline(Point p1,Point p2){

LINE tl;

tl.a=p2.y-p1.y; tl.b=p1.x-p2.x;

tl.c=p1.y*p2.x-p1.x*p2.y;

if (tl.a

return tl;

}

inline double MAX(double x,double y){return x>y?x:y;}

inline double MIN(double x,double y){return x

bool intersect(LINESEG u,LINESEG v){

return MAX(u.st.x,u.ed.x)>=MIN(v.st.x,v.ed.x)

&& MAX(v.st.x,v.ed.x)>=MIN(u.st.x,u.ed.x)

&& MAX(u.st.y,u.ed.y)>=MIN(v.st.y,v.ed.y)

&& MAX(v.st.y,v.ed.y)>=MIN(u.st.y,u.ed.y)

&& multiply(v.st,u.ed,u.st)*multiply(u.ed,v.ed,u.st)>=0

&& multiply(u.st,v.ed,v.st)*multiply(v.ed,u.ed,v.st)>=0;

}

bool intersect_A(LINESEG u,LINESEG v){

相关主题