poj-2504 (计算几何)

Description

The Archeologists of the Current Millenium (ACM) now and then discover ancient artifacts located at vertices of regular polygons. The moving sand dunes of the desert render the excavations difficult and thus once three vertices of a polygon are discovered there is a need to cover the entire polygon with protective fabric.

Input

Input contains multiple cases. Each case describes one polygon. It starts with an integer n <= 50, the number of vertices in the polygon, followed by three pairs of real numbers giving the x and y coordinates of three vertices of the polygon. The numbers are separated by whitespace. The input ends with a n equal 0, this case should not be processed.

Output

For each line of input, output one line in the format shown below, giving the smallest area of a rectangle which can cover all the vertices of the polygon and whose sides are parallel to the x and y axes.

Sample Input

4
10.00000 0.00000
0.00000 -10.00000
-10.00000 0.00000
6
22.23086 0.42320
-4.87328 11.92822
1.76914 27.57680
23
156.71567 -13.63236
139.03195 -22.04236
137.96925 -11.70517
0

Sample Output

Polygon 1: 400.000
Polygon 2: 1056.172
Polygon 3: 397.673

题目题意:有一个n边形,现在只给你3个点的坐标,让你求一个边与x轴y轴平行的最小的矩形可以覆盖,这个n变形。

题目分析:其实这个题目还是通过暴力来的,给我三个点,我们可以求出外接圆的圆心,然后通过矢量的旋转,我们可以求出其他点的坐标,我们就记录最高的,最左的,最右的,最低的,点,就可以算出矩形面积了。

算圆心的时候,就利用距离相等列方程,为了便于阅读,我把推导式列在下面,代码中的变量,也没有改变。

假设o(x,y),其他三个点(x1,y1),(x2,y2),(x3,y3)

则方程为(x-x1)^2+(y-y1)^2=(x-x2)^2+(y-y2)^2

化简得:(x1^2+y1^2)-(x2^2+y2^2)=x(2*x1-2*x2)+y(2*y1-2*y2)

同理得:(x1^2+y1^2)-(x3^2+y3^2)=x(2*x1-2*x3)+y(2*y1-2*y3)

令A=(x1^2+y1^2)-(x2^2+y2^2)  B=(x1^2+y1^2)-(x3^2+y3^2)

a=2(x1-x2)   b=2(y1-y2)    c=2(x1-x3)  d=2(y1-y3)

记得y=(A*c-B*a)/(b*c-d*a)   x=(B-y*d)/c

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
const double PI=acos(-1);
using namespace std;

struct note
{
    double x,y,r;
}p[3];

struct note get_o()//求圆心
{
    struct note o;
    p[0].r=p[0].x*p[0].x+p[0].y*p[0].y;
    p[1].r=p[1].x*p[1].x+p[1].y*p[1].y;
    p[2].r=p[2].x*p[2].x+p[2].y*p[2].y;
    double A=p[0].r-p[1].r;
    double B=p[0].r-p[2].r;
    double a=2*p[0].x-2*p[1].x;
    double b=2*p[0].y-2*p[1].y;
    double c=2*p[0].x-2*p[2].x;
    double d=2*p[0].y-2*p[2].y;
    o.y=(A*c-B*a)/(b*c-d*a);
    o.x=(B-o.y*d)/c;
    return o;
};
void solve(int n)
{
    struct  note o=get_o();
    double maxh,maxd,maxl,maxr;
    maxl=maxr=p[0].x;
    maxh=maxd=p[0].y;
    double r=2*PI/n;
    for (int i=0;i<n;i++) {//求每一个点的坐标
        double tx=(p[0].x-o.x)*cos(i*r)-(p[0].y-o.y)*sin(i*r)+o.x;
        double ty=(p[0].x-o.x)*sin(i*r)-(p[0].y-o.y)*cos(i*r)+o.y;
        maxl=min(maxl,tx);//按照要求更新
        maxr=max(maxr,tx);
        maxh=max(maxh,ty);
        maxd=min(maxd,ty);
    }
    printf("%.3f\n",(maxr-maxl)*(maxh-maxd));
}
int main()
{
    int n,icase=1;
    while (scanf("%d",&n)!=EOF) {
        if (n==0) break;
        scanf("%lf%lf%lf%lf%lf%lf",&p[0].x,&p[0].y,&p[1].x,&p[1].y,&p[2].x,&p[2].y);
        printf("Polygon %d: ",icase++);
        solve(n);
    }
    return 0;
}





































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值