题目:给你正多边形的三个点,求出能够包裹这个凸多变的平行于坐标轴的矩形的最小面积。
分析:计算几何、简单题。利用已知三点确定两条线段,求两条线断的垂直平分线,计算出外接圆圆心坐标和半径。
将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; }