啥叫重心?
我把它抽象的了解為幾個頂點均分權重。三個點及以上才能構成一個簡單的平面多邊形,三角形是最簡單的多邊形。三角形的重心就是三個頂點均分權重。
三角形重心
通過一個三角形重心公式來看多邊形重心公式,若一個三角形有三個點,分别為(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。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2csQzYU9ENBRkT6FleYhnRzwEMW1mY1RzRapnTtxkb5ckYplTeMZTTINGMShUYfRHelRHLwEzX39GZhh2css2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xyayFWbyVGdhd3LcV2Zh1Wa9M3clN2byBXLzN3btg3Pn5GcuITN0QzNwQTMzIzNwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
先給出它的重心公式:
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 = ∑ i = 1 n − 2 s i ∗ ( 以 s i 為 面 積 的 三 個 點 橫 坐 标 之 和 ) 3 ∑ i = 1 n − 2 s i x=\frac{ \sum_{i=1}^{n-2}s_i*(以s_i為面積的三個點橫坐标之和) }{3\sum_{i=1}^{n-2}s_i} x=3∑i=1n−2si∑i=1n−2si∗(以si為面積的三個點橫坐标之和)
y = ∑ i = 1 n − 2 s i ∗ ( 以 s i 為 面 積 的 三 個 點 縱 坐 标 之 和 ) 3 ∑ i = 1 n − 2 s i y=\frac{ \sum_{i=1}^{n-2}s_i*(以s_i為面積的三個點縱坐标之和) }{3\sum_{i=1}^{n-2}s_i} y=3∑i=1n−2si∑i=1n−2si∗(以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(x2−x1)(y3−y1)−(y2−y1)(x3−x1)
這個公式是要加絕對值的,但在計算重心時,别加。
貼個題目:
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;
}