原本是一道题,从中分离出来的:点击打开链接
计算多边形重心方法:
(1)划分多边形为三角形:以多边形的一个顶点V为源点(V可取输入的第一个顶点),作连结V与所有非相邻顶点的线段,即将原N边形或分为(N-2)个三角形;
(2)求每个三角形的重心和面积:
设某个三角形的重心为G(cx,cy),顶点坐标分别为A1(x1,y1),A2(x2,y2),A3(x3,y3),则有cx = (x1 + x2 + x3)/3.同理求得cy。求面积的方法是s = ( (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1) ) / 2,当A1,A2,A3顺时针排列时取-,否则取正(此定理不证)。事实上,在求每个三角形时不需要辨别正负,之后有方法抵消负号,见下述。
(3)求原多边形的重心:
公式:cx = (∑ cx[i]*s[i]) / ∑s[i]; cy = (∑ cy[i]*s[i] ) / ∑s[i];其中(cx[i], cy[i]), s[i]分别是所划分的第i个三角形的重心坐标和面积。由题“ connect the points in the given order”知每个s[i]的正负号相同,故而∑ cx[i]*s[i]能与∑s[i]消号,所以根本不需要在第(2)步判断每个s[i]的正负。另外,在(2)中求每个重心坐标时要除以3,实际上不需要在求每个三角形坐标时都除以3,只需要求出∑ cx[i]*s[i]后一次性除以3即可。即是多边形重心坐标变为:cx = (∑ cx[i]*s[i]) / (3*∑s[i]); cy = (∑ cy[i]*s[i] ) / (3*∑s[i]);
总结:
每个三角形重心:cx = x1 + x2 + x3;cy同理。
每个三角形面积:s = ( (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1) ) / 2;
多边形重心:cx = (∑ cx[i]*s[i]) / (3*∑s[i]); cy = (∑ cy[i]*s[i] ) / (3*∑s[i]);
#include<stdio.h>
int main()
{
int n,i;
int x1,y1,x2,y2,x3,y3;
double sum_x=0,sum_y=0,sum_s=0;
scanf("%d",&n);
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
for(i=1; i<=n-2; i++)
{
scanf("%d%d",&x3,&y3);
double s=((x2-x1)*(y3-y1)-(x3-x1)*(y2-y1))/2.0;
sum_x+=(x1+x2+x3)*s;
sum_y+=(y1+y2+y3)*s;
sum_s+=s;
x2=x3;
y2=y3;
}
printf("%.2lf %.2lf\n",sum_x/sum_s/3.0,sum_y/sum_s/3.0);
return 0;
}