南阳理工:多边形重心问题

来源:互联网 发布:剑网三御姐脸捏脸数据 编辑:程序博客网 时间:2024/05/15 14:13

多边形重心问题

时间限制:3000 ms  |  内存限制:65535 KB
难度:5
描述
在某个多边形上,取n个点,这n个点顺序给出,按照给出顺序将相邻的点用直线连接, (第一个和最后一个连接),所有线段不和其他线段相交,但是可以重合,可得到一个多边形或一条线段或一个多边形和一个线段的连接后的图形;
如果是一条线段,我们定义面积为0,重心坐标为(0,0).现在求给出的点集组成的图形的面积和重心横纵坐标的和;
输入
第一行有一个整数0<n<11,表示有n组数据;
每组数据第一行有一个整数m<10000,表示有这个多边形有m个顶点;
输出
输出每个多边形的面积、重心横纵坐标的和,小数点后保留三位;
样例输入
3  3  0 1  0 2  0 3  3  1 1  0 0  0 1  4  1 1  0 0  0 0.5  0 1
样例输出
0.000 0.000  0.500 1.000  0.500 1.000
题意:任给一个多边形(给出的时候有些边可能会重合),求这个多边型的面积和重心坐标。
思路:我们学习过三角形的重心公式,x'=(x1+x2+x3)/3,y'=(y1+y2+y3)/3,这个公式能不能直接推广呢?当然不能!错误的推广公式是“质点系重心公式”,即如果认为多边形的质量仅分布在其顶点上,且均匀分布,则这个公式是对的。但是,现在多边形的质量是均匀分布在其内部区域上的,也就是说,是与面积有关的!  
剖分成N个三角形,分别求出其重心和面积,这时可以想象,原来质量均匀分布在内部区域上,而现在质量仅仅分布在这N个重心点上(等价变换),这时候就可以利用刚才的质点系重心公式了。
不过,要稍微改一改,改成加权平均数,因为质量不是均匀分布的,每个质点代表其所在三角形,其质量就是该三角形的面积有向面积!),——这就是权!

#include<stdio.h>
#include<math.h>
struct point
{
    double x,y;
}p[10010];
double getarea(struct point p1,struct point p2)
{
    return p1.x*p2.y-p1.y*p2.x;
}
int main()
{
    int n,i,T;
    double x,y,s,temp;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(i=0;i<n;i++)
            scanf("%lf %lf",&p[i].x,&p[i].y);
        p[n]=p[0];
        for(i=0,s=x=y=0;i<n;i++)
        {
            temp=getarea(p[i],p[i+1])/2.0;//各个三角形的有向面积
            s+=temp;
            x+=temp*(p[i].x+p[i+1].x)/3.0;
            y+=temp*(p[i].y+p[i+1].y)/3.0;
        }
        if(fabs(s-0)<0.0000001)
            printf("0.000 0.000\n");
        else
            printf("%.3lf %.3lf\n",fabs(s),(x+y)/s);
    }
    return 0;
}