计算几何之多边形重心

啥叫重心?

我把它抽象的理解为几个顶点均分权重。三个点及以上才能构成一个简单的平面多边形,三角形是最简单的多边形。三角形的重心就是三个顶点均分权重。

三角形重心

通过一个三角形重心公式来看多边形重心公式,若一个三角形有三个点,分别为(x1,y1),(x2,y2),(x3,y3),那么三角形的重心公式为:
x = x 1 + x 2 + x 3 3 , y = y 1 + y 2 + y 3 3 x=\frac{x1+x2+x3}{3}, y=\frac{y1+y2+y3}{3} x=3x1+x2+x3,y=3y1+y2+y3
每个点的横权值相加除以3,每个纵权值相加除以3。

多边形重心

现在我们有一个五边形,有5个点,其中S1为三角形△ABC的面积,同理有S2,S3。

先给出它的重心公式:
x = ( x 1 + x 2 + x 3 ) s 1 + ( x 1 + x 3 + x 4 ) s 2 + ( x 1 + x 4 + x 5 ) s 3 3 ( s 1 + s 2 + s 3 ) x=\frac{(x1+x2+x3)s1+(x1+x3+x4)s2+(x1+x4+x5)s3}{3(s1+s2+s3)} x=3(s1+s2+s3)(x1+x2+x3)s1+(x1+x3+x4)s2+(x1+x4+x5)s3
y = ( y 1 + y 2 + y 3 ) s 1 + ( y 1 + y 3 + y 4 ) s 2 + ( y 1 + y 4 + y 5 ) s 3 3 ( s 1 + s 2 + s 3 ) y=\frac{(y1+y2+y3)s1+(y1+y3+y4)s2+(y1+y4+y5)s3}{3(s1+s2+s3)} y=3(s1+s2+s3)(y1+y2+y3)s1+(y1+y3+y4)s2+(y1+y4+y5)s3
相当于求出三个三角形的重心,再根据三角形的面积去均分权重。相同的道理,可以画一画六边形,七边形,是一样的道理。
所以给出n边形重心公式:
x = <munderover> i = 1 n 2 </munderover> s i ( s i ) 3 <munderover> i = 1 n 2 </munderover> s i x=\frac{ \sum_{i=1}^{n-2}s_i*(以s_i为面积的三个点横坐标之和) }{3\sum_{i=1}^{n-2}s_i} x=3i=1n2sii=1n2si(si)
y = <munderover> i = 1 n 2 </munderover> s i ( s i ) 3 <munderover> i = 1 n 2 </munderover> s i y=\frac{ \sum_{i=1}^{n-2}s_i*(以s_i为面积的三个点纵坐标之和) }{3\sum_{i=1}^{n-2}s_i} y=3i=1n2sii=1n2si(si)
就是酱紫,是不是很好理解0.0
Tip:计算三角形面积最好使用叉积,海伦公式会损失太多精度。给一下三角形叉积求三角形的公式。但在计算叉积时取点要注意,一定要按逆时针连图,顺时针计算的结果是负的,友情提示,不要加绝对值(会损失精度)。假如三角形有三个点A(x1, y1), B(x2, y2), C(x3, y3),公式为 :
S = ( x 2 x 1 ) ( y 3 y 1 ) ( y 2 y 1 ) ( x 3 x 1 ) 2 S=\frac{(x2-x1)(y3-y1) - (y2-y1)(x3-x1)}{2} S=2(x2x1)(y3y1)(y2y1)(x3x1)
这个公式是要加绝对值的,但在计算重心时,别加。
贴个题目:
hdu1115 Lifting the Stone
这题就不能加绝对值…跟着公式敲就行

#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
#define PI 3.1415926
using namespace std;
typedef long long ll;
//叉积求面积
double getarea(double x1, double y1, double x2, double y2, double x3, double y3) {
  return ((x2-x1)*(y3-y1) - (y2-y1)*(x3-x1)) / 2;
}
int main() {
  fio
  int t, n; 
  cin >> t;
  double x1, y1, x2, y2, x3, y3, ansx, ansy, allarea, area; 
  while(t--) {
    ansx = 0; ansy = 0; allarea = 0;
     cin >> n;
     cin >> x1 >> y1 >> x2 >> y2;
     for(int i = 2; i < n; ++i) {
       cin >> x3 >> y3;
       area = getarea(x1, y1, x2, y2, x3, y3);
       cout << area << endl;
       allarea += area;
       ansx += (x1+x2+x3) * area;
       ansy += (y1+y2+y3) * area;
       x2 = x3; y2 = y3;
   }
   printf("%.2lf %.2lf\n", ansx / allarea / 3.0, ansy / allarea / 3.0);
  }
  return 0;
}
全部评论

相关推荐

牛客279957775号:铁暗恋
点赞 评论 收藏
分享
点赞 1 评论
分享
牛客网
牛客企业服务