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