题意是给一个 n 边形,给出沿逆时针方向分布的各顶点的坐标,求出 n 边形的重心。
求多边形重心的情况大致上有三种:
一、多边形的质量都分布在各顶点上,像是用轻杆连接成的多边形框,各顶点的坐标为Xi,Yi,质量为mi,则重心坐标为:
X = ∑( xi * mi ) / ∑ mi ;
Y = ∑( yi * mi) / ∑ mi;
若每个顶点的质量相等,则重心坐标为:
X = ∑ xi / n;
Y = ∑ yi / n;
二、多边形的质量分布均匀,像是用密度相同的材料制成的多边形板子,多采用将多边形分割成 n - 2 个三角形,(个人喜欢以原点和多边形逆时针方向上连续两点作为每个三角形的三顶点,因为算面积使用的是向量叉乘,用原点可以减少对三角形两边向量的求解(直接用坐标即可),而叉乘得到的是有向面积,对结果并无影响)再求出每个三角形的重心:
X = (x0 + x1 + x2) / 3;
Y = (y0 + y1 + y2) / 3;
再将各重心视作情况一处理即可
要注意的是这种情况下并不是求三角形重心的简单推广,也就是说不能简单的用不断分割三角形求重心的方法去做
三、多边形的质量分布不均匀,此时要用到积分的方法。
本题属于第二种情况,所以按照第二种情况的处理方式处理即可。
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <iomanip> 5 using namespace std; 6 7 struct point 8 { 9 double x,y; 10 }pi[1000010]; 11 double cp(point a,point b) 12 { 13 return (a.x*b.y)-(a.y*b.x); 14 } 15 point gravity(point *p, int n) 16 { 17 double area = 0; 18 point center; 19 center.x = center.y = 0; 20 for (int i = 0; i < n-1; i++) 21 { 22 area += cp(p[i],p[i+1]); 23 center.x += cp(p[i],p[i+1]) * (p[i].x + p[i+1].x); 24 center.y += cp(p[i],p[i+1]) * (p[i].y + p[i+1].y); 25 /*此处其实是: 26 area += cp(p[i],p[i+1]) / 2; 27 center.x += (cp(p[i],p[i+1]) / 2)* ((p[i].x + p[i+1].x + 0) / 3); 28 center.y += (cp(p[i],p[i+1]) / 2)* ((p[i].y + p[i+1].y + 0) / 3); 29 但一些计算过程中的常数在实际运算时被总写了。 30 */ 31 } 32 area += cp(p[n-1],p[0]);//area += cp(p[n-1],p[0]) / 2; 33 center.x += cp(p[n-1],p[0]) * (p[n-1].x + p[0].x);//center.x += (cp(p[n-1],p[0]) / 2) * ((p[n-1].x + p[0].x + 0) / 3); 34 center.y += cp(p[n-1],p[0]) * (p[n-1].y + p[0].y);//center.y += (cp(p[n-1],p[0]) / 2) * ((p[n-1].y + p[0].y + 0) / 3); 35 center.x /= 3*area;//center.x /= area; 36 center.y /= 3*area;//center.y /= area; 37 return center; 38 } 39 40 int main() 41 { 42 int t; 43 scanf("%d",&t); 44 while(t--) 45 { 46 int n; 47 scanf("%d",&n); 48 for(int i = 0; i < n; i++) 49 scanf("%lf %lf",&pi[i].x,&pi[i].y); 50 point out = gravity(pi,n); 51 printf("%.2f %.2f\n",out.x,out.y); 52 } 53 return 0; 54 }
原文地址:https://www.cnblogs.com/Taskr212/p/9459412.html
时间: 2024-10-06 14:51:05