多边形重心问题
时间限制: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
这道题也是看了一个PPT后才会做的,PPT思路如下:三角形的重心是: (x1+x2+x3) / 3,(y1+y2+y3) / 3,可以推广否?
错误的推广公式是“质点系重心公式”,即如果认为多边形的质量仅分布在其顶点上,且均匀分布,则这个公式是对的。 但是,现在多边形的质量是均匀分布在其内部区域上的,也就是说,是与面积有关的!
剖分成N个三角形,分别求出其重心和面积,这时可以想象,原来质量均匀分布在内部区域上,而现在质量仅仅分布在这N个重心点上(等假变换),这时候就可以利用刚才的质点系重心公式了。 不过,要稍微改一改,改成加权平均数,因为质量不是均匀分布的,每个质点代表其所在三角形,其质量就是该三角形的面积(有向面积!),——这就是权!
1 #include <cstdio> 2 #include <iostream> 3 #include <cmath> 4 5 using namespace std; 6 7 int main() 8 { 9 int T, n; 10 double s, tmp, x1, x2, y1, y2, tx, ty, Gx, Gy; 11 scanf("%d", &T); 12 while(T--) 13 { 14 s = Gx = Gy = 0; 15 scanf("%d", &n); 16 if(n > 1) 17 { 18 scanf("%lf%lf", &x1, &y1); 19 tx = x1; 20 ty = y1; 21 n--; 22 while(n--) 23 { 24 scanf("%lf%lf", &x2, &y2); 25 tmp = (x1*y2 - y1*x2)/2;//计算各个三角形的有向面积 26 Gx += tmp*(x1 + x2)/3.0;// 计算每个三角形的重心的横纵坐标并以该三角形的有向面积(与质量等价)作为权重 27 Gy += tmp*(y1 + y2)/3.0; 28 s += tmp; 29 x1 = x2; 30 y1 = y2; 31 } 32 tmp = (x1*ty - y1*tx)/2; 33 Gx += tmp*(x1 + tx)/3.0; 34 Gy += tmp*(y1 + ty)/3.0; 35 s += tmp; 36 } 37 if(fabs(s) < 10e-4) 38 printf("0.000 0.000\n"); 39 else 40 printf("%.3lf %.3lf\n", fabs(s), (Gx+Gy)/s); // 注意都是有向的 41 } 42 return 0; 43 }
功不成,身已退