Center of Masses 

Find out the center of masses of a convex polygon.

 

Input 

A series of convex polygons, defined as a number n ($n \le 100$) stating the number of points of the polygon, followed by n different pairs of integers (in no particular order), denoting the x and y coordinates of each point. The input is finished by a fake ``polygon" with m (m < 3) points, which should not be processed.

 

Output 

For each polygon, a single line with the coordinates x and y of the center of masses of that polygon, rounded to three decimal digits.

 

Sample Input 

4 0 1 1 1 0 0 1 0
3 1 2 1 0 0 0
7
-4 -4
-6 -3
-4 -10
-7 -12
-9 -8
-3 -6
-8 -3
1

 

Sample Output 

0.500 0.500
0.667 0.667
-6.102 -7.089

 


Miguel Revilla  2000-08-21
#include <iostream>
#include <vector>
#include <algorithm>
#include <iomanip>

using namespace std;

struct Point{
    long long x;//
    long long y;
    Point(long long a = 0, long long b = 0){x = a, y = b;}
};

bool cmp(Point a, Point b){
    return (a.x * b.y < b.x * a.y || (a.x * b.y == b.x * a.y && a.x * a.x + a.y * a.y < b.x * b.x + b.y * b.y));
}

class CenterOfMasses{
private:
    vector<Point> mass;
    double sumArea;
    double sumX;
    double sumY;
    double calculateArea(Point a, Point b, Point c);
public:
    void initialize();
    void readCase(int n);
    void computing();
    void outResult();
};

void CenterOfMasses::initialize(){
    mass.clear();
    sumArea = 0;
    sumX = 0;
    sumY = 0;
}

void CenterOfMasses::readCase(int n){
    long long x, y;
    while(n--){
        cin >> x >> y;
        mass.push_back(Point(x, y));
    }
}

double CenterOfMasses::calculateArea(Point a, Point b, Point c){
    double area;
    area = a.x * b.y + b.x * c.y + c.x * a.y - a.y * b.x - b.y * c.x - c.y * a.x;
    return area / 2;
}

void CenterOfMasses::computing(){
    Point base = mass[0];
    for(int i = 1; i < mass.size(); i++){
        if(mass[i].y < base.y || (mass[i].y == base.y && mass[i].x < base.x)){
            base = mass[i];
            mass[i] = mass[0];
            mass[0] = base;
        }
    }
    for(int i = 0; i < mass.size(); i++){
        mass[i].x -= base.x;
        mass[i].y -= base.y;
    }
    sort(mass.begin() + 1, mass.end(), cmp);
    for(int i = 2; i < mass.size(); i++){
        if(mass[i].x * mass[i - 1].y == mass[i].y * mass[i - 1].x){
            mass.erase(mass.begin() + i - 1);
        }
    }
    mass.push_back(Point(0, 0));
    for(int i = mass.size() - 1; i > 0; i--){
        mass[i].x -= mass[i - 1].x;
        mass[i].y -= mass[i - 1].y;
    }
    for(int i = 2; i < mass.size() - 1; i++){
        if(mass[i + 1].x * mass[i].y - mass[i].x * mass[i + 1].y <= 0){
            mass[i].x += mass[i + 1].x;
            mass[i].y += mass[i + 1].y;
            mass.erase(mass.begin() + i + 1);
            i == 2 ? i-- : i -= 2;
        }
    }
    mass[0].x += base.x;
    mass[0].y += base.y;
    for(int i = 1; i < mass.size(); i++){
        mass[i].x += mass[i - 1].x;
        mass[i].y += mass[i - 1].y;
    }
    Point a = mass[0];
    Point b = mass[1];
    Point c;
    double area;
    for(int i = 2; i < mass.size() - 1; i++){
        c = mass[i];
        area = calculateArea(b, a, c);
        sumArea += area;
        sumX += (a.x + b.x + c.x) * area;
        sumY += (a.y + b.y + c.y) * area;
        b = c;
    }

}

void CenterOfMasses::outResult(){
    cout << setiosflags(ios::fixed) << setprecision(3) << sumX / sumArea / 3 << ' ';
    cout << setiosflags(ios::fixed) << setprecision(3) << sumY / sumArea / 3 << endl;
}

int main(){
    CenterOfMasses com;
    int n;
    while(cin >> n && n >= 3){
        com.initialize();
        com.readCase(n);
        com.computing();
        com.outResult();
    }
    return 0;
}