1. 程式人生 > >POJ 3855 計算幾何·多邊形重心

POJ 3855 計算幾何·多邊形重心

pri struct scan operator The connect scanf details main

思路:

多邊形面積->任選一個點,把多邊形拆成三角,叉積一下

三角形重心->(x1+x2+x3)/3,(y1+y2+y3)/3

多邊形重心公式題目中有,套一下就好了

計算多邊形重心方法:

(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]);

https://blog.csdn.net/nhl19961226/article/details/68941585

//By SiriusRen
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n,cases;double S,ts;
struct P{double x,y;}p[105],ans;
P operator-(P a,P b){P c;c.x=a.x-b.x,c.y=a.y-b.y;return c;}
double
operator*(P a,P b){return a.x*b.y-a.y*b.x;} int main(){ while(scanf("%d",&n)&&n){ S=ans.x=ans.y=0; for(int i=0;i<n;i++)scanf("%lf%lf",&p[i].x,&p[i].y); for(int i=0;i<n;i++){ ts=p[i]*p[(i+1)%n];S+=ts; ans.x+=ts*(p[i].x+p[(i+1)%n].x)/3; ans.y+=ts*(p[i].y+p[(i+1)%n].y)/3; }printf("Stage #%d: %lf %lf\n",++cases,ans.x/S,ans.y/S); } }

POJ 3855 計算幾何·多邊形重心