1. 程式人生 > >求任意多邊形的重心

求任意多邊形的重心

原本是一道題,從中分離出來的:點選開啟連結

計算多邊形重心方法:

(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;
}