Bounding box POJ - 2504 计算几何


Bounding box    题目链接


题意:给你一个正n边形的三个点,让你求出能够包含这个多边形所有点的矩形的最小面积,矩形平行于坐标轴。


思路: 首先通过三点确定多边形的外接圆心,然后用到向量旋转公式,求出多边形的每个点,找到最大和最小的坐标

然后算出面积。

公式我也不知道怎么推  ,记一下模板吧: x' ,y' 已知的某一点, x0 ,y0 外接圆心。


#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;

const double pi=acos(-1);
struct Node{

    double  x,y;
}a1,b1,c1;
int n;
Node calu(Node a,Node b,Node c)
{
    Node 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(Node a,Node d)
{
    double r=2*pi/n;
    double mxx,mnx,mxy,mny;
    mxx=mnx=a.x,mxy=mny=a.y;
    for(int i=0;i<n;i++)
    {
        double mx=(a.x-d.x)*cos(r*i)-(a.y-d.y)*sin(r*i)+d.x;
        double my=(a.x-d.x)*sin(r*i)-(a.y-d.y)*cos(r*i)+d.y;
        mxx=max(mx,mxx);
        mnx=min(mnx,mx);
        mxy=max(mxy,my);
        mny=min(mny,my);
    }
    return (mxx-mnx)*(mxy-mny);

}
int main()
{
    int kase=1;
    while(scanf("%d",&n)&&n)
    {
        scanf("%lf%lf%lf%lf%lf%lf",&a1.x,&a1.y,&b1.x,&b1.y,&c1.x,&c1.y);
        Node d=calu(a1,b1,c1);
        printf("Polygon %d: %.3f\n",kase++,solve(a1,d));
    }
    return 0;
}



模板  由三个点求外接圆面积:

Node calu(Node a,Node b,Node c)
{
    Node 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;
}


模板 由外接圆求正 n 边形 的每个顶点。


double solve(Node a,Node d)
{
    double r=2*pi/n;
    double mxx,mnx,mxy,mny;
    mxx=mnx=a.x,mxy=mny=a.y;
    for(int i=0;i<n;i++)
    {
        double mx=(a.x-d.x)*cos(r*i)-(a.y-d.y)*sin(r*i)+d.x;
        double my=(a.x-d.x)*sin(r*i)-(a.y-d.y)*cos(r*i)+d.y;
        mxx=max(mx,mxx);
        mnx=min(mnx,mx);
        mxy=max(mxy,my);
        mny=min(mny,my);
    }
    return (mxx-mnx)*(mxy-mny);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值