matlab 二维凸包面积,PKU——3348——(凸包和计算多边形面积)

这篇博客介绍了如何使用C++实现计算多边形的凸包,并通过极角排序和叉乘判断实现快速求解。文章详细阐述了算法步骤,包括找到最左下点、计算极角、进行凸包遍历以及计算多边形面积和周长的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//3348 Accepted 264K 0MS C++ 4016B//典型的凸包和计算多边形面积#include#include#include#include#include#includeusingnamespacestd ;#defineunllong unsigned long long#defineunint unsigned int#defineprintline  printf( "\n" )typedeflonglongllong ;//const double PI = 2.0 * acos( 0.0 ) ;#definezero(x) (((x)>0?(x):-(x))

{doublex ;doubley ;doublek ;

};structPOINT point[size] ;intstack[size] ;inttop=2;intinn ;doubleoutarea ;doublefdist(doublex1,doubley1,doublex2,doubley2 )

{returnsqrt( (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2) ) ;

}voidinput()

{intleftdown=0;for(inti=0; i

scanf("%lf %lf",&point[i].x,&point[i].y ) ;//if( miny>point[i].y || miny==point[i].y&&minx>point[i].x )if( point[leftdown].y>point[i].y||zero(point[leftdown].y-point[i].y)&&point[leftdown].x>point[i].x )

leftdown=i ;//找到最左下的点}doubletemp ;

temp=point[0].x ; point[0].x=point[leftdown].x ; point[leftdown].x=temp ;

temp=point[0].y ; point[0].y=point[leftdown].y ; point[leftdown].y=temp ;for(inti=1; i

point[i].k=atan2( point[i].y-point[0].y, point[i].x-point[0].x ) ;

}//以点(minx, miny)计算极角}doublexmult( POINT&p1, POINT&p2, POINT&p0 )

{//计算叉乘--线段旋转方向和对应的四边形的面积--返回(p1-p0)*(p2-p0)叉积//if叉积为正--p0p1在p0p2的顺时针方向; if(x==0)共线return(p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y) ;

}intgramcmp1(constvoid*a,constvoid*b )

{structPOINT*c=(structPOINT*)a ;structPOINT*d=(structPOINT*)b ;if( c->k-d->k>eps )return1;elseif( c->k-d->kx-d->x>0?1: -1;

}intgramcmp(constvoid*a,constvoid*b )

{structPOINT*c=(structPOINT*)a ;structPOINT*d=(structPOINT*)b ;doublexmult_val=xmult(*c,*d, point[0] ) ;if( xmult_val>eps )return-1;elseif( xmult_valx-d->x>0?1: -1;//else//return fdist( c->x,c->y,point[0].x,point[0].y )>fdist(d->x,d->y,point[0].x,point[0].y)? -1:1 ;}voidgramham()

{//凸包的点存在于stack[]中qsort( point+1, inn-1,sizeof(point[1]), gramcmp ) ;//极坐标排序--注意只有(n-1)个点//int stack[size] ; int top = 2 ;stack[0]=0; stack[1]=1; stack[2]=2; top=2;for(inti=3; i

{while( top>=1&&xmult( point[i], point[stack[top]], point[stack[top-1]] )>=-1*eps )

top--;//顺时针方向--删除栈顶元素stack[++top]=i ;//新元素入栈}/*for( int i=0; i<=top; i++ )

{

//printf( "%lf===%lf\n",point[stack[i]].x, point[stack[i]].y ) ;

cout <

}*/}doubleflen_poly()

{//计算凸包的周长doublelen=0.0;doublex1, x2, y1, y2 ;for(inti=0; i

x1=point[stack[i+1]].x ; x2=point[stack[i]].x ;

y1=point[stack[i+1]].y ; y2=point[stack[i]].y ;

len+=fdist( x1, y1, x2, y2 ) ;

}

x1=point[stack[0]].x ; x2=point[stack[top]].x ;

y1=point[stack[0]].y ; y2=point[stack[top]].y ;

len+=fdist( x1, y1, x2, y2 ) ;returnlen ;

}doublefarea_poly(intn, POINT poly[] )

{doublearea=0.0;doubles1=0.0, s2=0.0;for(inti=0; i

{

s1+=poly[stack[(i+1)%n]].y*poly[stack[i%n]].x ;

s2+=poly[stack[(i+1)%n]].y*poly[stack[(i+2)%n]].x ;

}returnfabs( s1-s2 )/2;

}voidprocess()

{

gramham() ;//保存好凸包的点在stack[]中outarea=farea_poly( top+1, point ) ;

}voidoutput()

{

printf("%d\n", (int)outarea/50) ;

}intmain()

{//freopen( "fc.in", "r", stdin ) ;//freopen( "fc.out","w",stdout ) ;//freopen( "in.txt", "r", stdin ) ;while( scanf("%d",&inn )!=EOF )

{

input() ;

process() ;

output() ;

}return0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值