【POJ2504】Bounding box(计算几何)

博客记录了如何解决POJ2504问题,该问题涉及计算几何,要求找到一个边平行于坐标轴且面积最小的矩形来覆盖正n边形的所有点。通过求解外接圆圆心和应用向量旋转公式,可以得出其余点的坐标并确定边界值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

记录一个菜逼的成长。。

题目链接
题目大意:
给你一个正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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值