UVa 10577 - Bounding box

来源:互联网 发布:手机淘宝流量钱包 编辑:程序博客网 时间:2024/05/17 12:20

题目:给你正多边形的三个点,求出能够包裹这个凸多变的平行于坐标轴的矩形的最小面积。

分析:计算几何、简单题。利用已知三点确定两条线段,求两条线断的垂直平分线,计算出外接圆圆心坐标和半径。

           

            将a点作为起点,利用三角函数的和角函数计算出每个点的位置。

            cos(a`) = cos(a+da) = cos(a)*cos(da) - sin(a)*sin(da);

            sin(a`) = sin(a+da) = sin(a)*cos(da) + sin(da)*cos(a);

            (xi - x1,yi -y1) = (r*cos(a+da*(i-1)),r*sin(a+da*(i-1))) ;

            (xi+1 - x1,yi+1 -y1) = (r*cos(a+da*i),r*sin(a+da*i)) ;

            推导得:(xi+1 - x1,yi+1 -y1) = ((xi - x1)*cos(da) - (yi -y1)*sin(da),(xi - x1)*sin(da) + (yi -y1)*cos(da))。

#include <iostream>#include <cstdlib>#include <cstdio>#include <cmath>using namespace std;typedef struct pnode{double x,y;pnode( double a, double b ){x = a;y = b;}pnode(){}}point;point poly[155];typedef struct lnode{double x,y,dx,dy;lnode( point a, point b ){x = a.x;y = a.y;dx = b.x-a.x;dy = b.y-a.y;}lnode(){};}line;//两点间距离 double dist( point a, point b ){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}//两直线交点   point crosspoint( line l, line m )  {double a1 = -l.dy,b1 = l.dx,c1 = l.dx*l.y-l.dy*l.x;  double a2 = -m.dy,b2 = m.dx,c2 = m.dx*m.y-m.dy*m.x;  double x = (c1*b2-c2*b1)/(a1*b2-a2*b1);  double y = (c1*a2-c2*a1)/(b1*a2-b2*a1);  return point( x, y );   }  int main(){double pi = acos(-1.0);int    n,t = 1;point  a,b,c;while ( ~scanf("%d",&n) && n ) {scanf("%lf%lf",&a.x,&a.y);scanf("%lf%lf",&b.x,&b.y);scanf("%lf%lf",&c.x,&c.y);//做两条线断的垂直平分线,利用交点 point  m1 = point( (a.x+b.x)/2, (a.y+b.y)/2 );line   l1 = line( m1, point( m1.x+b.y-a.y, m1.y-b.x+a.x ) );point  m2 = point( (c.x+b.x)/2, (c.y+b.y)/2 );line   l2 = line( m2, point( m2.x+b.y-c.y, m2.y-b.x+c.x ) ); //计算多边形外接圆的圆心和半径 point  cc = crosspoint( l1, l2 );double r  = dist( cc, a );//计算多由顶点double rcosx,cosy = cos(2*pi/n);double rsinx,siny = sin(2*pi/n);poly[0] = a;for ( int i = 1 ; i < n ; ++ i ) {rcosx = poly[i-1].x-cc.x;rsinx = poly[i-1].y-cc.y;poly[i].x = rcosx*cosy-rsinx*siny+cc.x;poly[i].y = rsinx*cosy+rcosx*siny+cc.y;}//求出边界点,计算面积 int minx = 0,maxx = 0,miny = 0,maxy = 0;for ( int i = 0 ; i < n ; ++ i ) {if ( poly[i].x < poly[minx].x ) minx = i;if ( poly[i].x > poly[maxx].x ) maxx = i;if ( poly[i].y < poly[miny].y ) miny = i;if ( poly[i].y > poly[maxy].y ) maxy = i;}double X = poly[maxx].x-poly[minx].x;double Y = poly[maxy].y-poly[miny].y;printf("Polygon %d: %.3lf\n",t ++,X*Y);}return 0;}