您的位置:首页 > 其它

求凸多边形的重心 例:hdu 1115 Lifting the Stone

2013-10-17 08:57 281 查看
1. 1 累加和求重心

设平面上有N 个离散数据点( xi , yi ) ( i = 1, 2, ., n) , 其

多边形重心G( . x1, . y1) 为:

  


  这是求多边形最简单直观的方法。可以直接利用离散数
据点的x, y坐标就能求图形重心。但是缺陷在于没有对离散
数据点所围图形做任何处理和分析,精度不够。

1. 2 算法一:在讲该算法时,先要明白下面几个定理。
定理1 已知三角形△A1A2A3的顶点坐标Ai ( xi , yi ) ( i =1, 2, 3) 。它的重心坐标为:

  xg = (x1+x2+x3) / 3 ;                       yg = (y1+y2+y3) / 3 ;

定理2 已知三角形△A1A2A3的顶点坐标Ai ( xi , yi ) ( i =1, 2, 3) 。该三角形的面积为:

  S =  ( (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1) ) / 2 ;

  △A1A2A3 边界构成逆时针回路时取+ , 顺时针时取 -。

  另外在求解的过程中,不需要考虑点的输入顺序是顺时针还是逆时针,相除后就抵消了。

  原理:将多边形划分成n个小区域, 每个小区域面积为σi ,重心为Gi ( . xi , . yi ) ,利用求平面薄板重心公式把积分变

  成累加和:

    

                           




                  

    由前面所提出的原理和数学定理可以得出求离散数据点所围多边形的一般重心公式:以Ai ( xi , yi ) ( i = 1, 2, ., n) 为顶点的任意N边形A1A2 .An ,将它划    分成N - 2个三角形(如图1) 。每个三角形的重心为Gi ( . xi , . yi ) ,面积为σi。那么多边形的重心坐标G( .x2, .y2) 为:

  


               


注:[ ] 表示由点p1(x1,  y1)、pi(xi,  yi)、pi+1 ( xi+1, yi+1)构成的三角形的面积

例题:HDU  1115 赤裸裸的求多边形的重心

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1115

代码如下:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
struct point
{
double x;
double y;
}p[1000010];

double area(point a, point b, point c)
{
return ((a.x- c.x) * (b.y - c.y) - (a.y - c.y) * (b.x- c.x)) / 2;
}

int  main()
{
int t;
int n;
point gravity;
double poly_area;
scanf("%d", &t);
for(int i = 0; i < t; i++)
{
scanf("%d", &n);
gravity.x = 0.0;
gravity.y = 0.0;
poly_area = 0.0;
scanf("%lf %lf", &p[0].x, &p[0].y);
scanf("%lf %lf", &p[1].x, &p[1].y);
for(int i = 2; i < n; i ++)
{
scanf("%lf %lf", &p[i].x, &p[i].y);
double temp = area(p[0], p[1], p[i]);
poly_area += temp;
gravity.x += (p[0].x + p[1].x + p[i].x) * temp;
gravity.y += (p[0].y + p[1].y + p[i].y) * temp;
p[1] = p[i];
}
gravity.x /= (3 * poly_area);
gravity.y /= (3 * poly_area);
printf("%.2lf %.2lf\n", gravity.x, gravity.y);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  凸多边形 重心