UVa 10577 - Bounding box

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

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

            UVa 10577 - Bounding box_第1张图片

            将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;
}

你可能感兴趣的:(UVa 10577 - Bounding box)