【POJ2504】Bounding box(计算几何)

来源:互联网 发布:plsql从excel导入数据 编辑:程序博客网 时间:2024/05/17 06:17

记录一个菜逼的成长。。

题目链接
题目大意:
给你一个正n边形的三个点,求一个边平行于坐标轴的面积最小的矩形,能覆盖正n边形的所有点。

这题用到向量旋转公式(逆时针旋转,若顺时针则r改为-r):
(x1x0)=(xx0)cos(r)+(yy0)sin(r);
(y1x0)=(xx0)sin(r)+(yy0)cos(r);
这应该好推的。

先求出外接圆的圆心,作为(x0,y0),然后将给出三点的任意一点作为(x’,y’)
然后就可以用上面的公式求出正n边形的其余点的坐标。
保存四个边界值就行了

ps:之前的博客里的代码头文件太长,,似乎会影响阅读。以后会改的。

#include <cstdio>#include <algorithm>#include <cmath>using namespace std;int INF = 0x3f3f3f3f;double pi = acos(-1);struct Point{    double x,y;}a,b,c;Point cal_cirle(Point a,Point b,Point c){    Point ret;    ret.x = ((b.y-c.y) * (pow(a.x,2)-pow(b.x,2)+pow(a.y,2)-pow(b.y,2)) - (a.y-b.y) * (pow(b.x,2)-pow(c.x,2)+pow(b.y,2)-pow(c.y,2))) / ((a.x-b.x)*(b.y-c.y)-(b.x-c.x)*(a.y-b.y)) / 2;    ret.y = -(a.x-b.x) / (a.y-b.y) * (ret.x - (a.x+b.x)/2) + (a.y+b.y) / 2;    return ret;}double solve(Point a,Point p,int n){    double r = 2 * pi / n;    double mxx = a.x,mnx = a.x,mxy = a.y,mny = a.y;    for( int i = 0; i < n; i++ ){        double tmpx = (a.x - p.x) * cos(i*r) - (a.y - p.y) * sin(i*r) + p.x;        double tmpy = (a.x - p.x) * sin(i*r) - (a.y - p.y) * cos(i*r) + p.y;        mxx = max(mxx,tmpx);        mnx = min(mnx,tmpx);        mxy = max(mxy,tmpy);        mny = min(mny,tmpy);    }    return (mxx - mnx) * (mxy - mny);}int main(){    int n,cas = 1;    while(~scanf("%d",&n),n){        scanf("%lf%lf%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y,&c.x,&c.y);        Point p = cal_cirle(a,b,c);        printf("Polygon %d: %.3f\n",cas++,solve(a,p,n));    }    return 0;}
0 0
原创粉丝点击