#include<algorithm>
#include<complex>
#include<ctype.h>
#include<iomanip>
#include<iostream>
#include<map>
#include<math.h>
#include<numeric>
#include<queue>
#include<set>
#include<stack>
#include<stdio.h>
#include<string>
#include<string>
#include<vector>

using namespace std;
typedef long long ll;

#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define ALL(v) (v).begin(), (v).end()
#define p(s) cout<<(s)<<endl
#define p2(s, t) cout << (s) << " " << (t) << endl
#define pn(s) cout << (#s) << " " << (s) << endl
#define p_yes() p("Yes")
#define p_no() p("No")

const ll mod = 1e9 + 7;
const ll inf = 1e18;

struct Point{
    ll x;
    ll y;
    Point(ll x, ll y): x(x), y(y) {}
    Point(): x(0), y(0) {}

    bool operator<(const Point &q) const
    {
        if(x == q.x){
            return y < q.y;
        }
        else{
            return x < q.x;
        }
    };

    bool isEqual(Point p){
        return x == p.x && y == p.y;
    }

    bool is_parallel(Point q){
        return x * q.y - y * q.x == 0;
    }

    Point operator - (const Point& q) const
    {
        return Point(x - q.x, y - q.y);
    }
};

bool is_straight_line(vector<Point> P){
    ll n = P.size();
    if(n<3) return true;

    Point v = P[1] - P[0];
    FOR(i, 2, P.size()){
        Point w = P[i] - P[0];
        if(!v.is_parallel(w)){
            return false;
        }
    }
    return true;
}

// 左端、右端のindexを返す
pair<int, int> leftAndRight(vector<Point> P){
    vector<Point> copy;
    for(auto p : P){
        copy.push_back(p);
    }

    sort(ALL(copy));
    auto left = copy[0];
    auto right = copy.back();

    int left_index = -1;
    int right_index = -1;

    // Pでのindexは?
    FOR(i, 0, P.size()){
        if(P[i].isEqual(left)){
            left_index = i;
        }
        else if(P[i].isEqual(right)){
            right_index = i;
        }
    }
    return make_pair(left_index, right_index);
}

// To find orientation of ordered triplet (p, q, r).
// The function returns following values
// 0 --> p, q and r are colinear
// 1 --> Clockwise
// 2 --> Counterclockwise
int orientation(Point p, Point q, Point r)
{
    ll val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
 
    if (val == 0)
        return 0; // colinear
    return (val > 0) ? 1 : 2; // clock or counterclock wise
}

double dot(complex<double> c0, complex<double> c1){
    return c0.real() * c1.real() + c0.imag() * c1.imag();
}

bool is_parallel(complex<double> c0, complex<double> c1){
    return c0.real() * c1.imag() - c0.imag() * c1.real() == 0;
}

void printAngle(Point left, Point center, Point right){
    // 全部複素数にして計算するか
    auto l = complex<double>(left.x, left.y);
    auto c = complex<double>(center.x, center.y);
    auto r = complex<double>(right.x, right.y);

    auto v = l - c;
    auto w = r - c;

    // v, wが平行なら確率なし
    if(is_parallel(v, w)){
        p(0);
        return;
    }

    double theta = acos( dot(v, w) / (abs(v) * abs(w)) );

    // 求めたかった二等分線の角度
    double theta2 = M_PI - theta;

    // それの360度における割合
    p(theta2 / (2*M_PI));
}

// ref
// https://www.sanfoundry.com/cpp-program-implement-gift-wrapping-algorithm-two-dimensions/
void convexHull(vector<Point> points)
{
    int n = points.size();
    vector<Point> ret;

    // There must be at least 3 points
    if (n < 3)
        return;
 
    // Initialize Result
    int next[n];
    for (int i = 0; i < n; i++)
        next[i] = -1;
 
    // Find the leftmost point
    int l = 0;
    for (int i = 1; i < n; i++)
        if (points[i].x < points[l].x)
            l = i;

    int count = 0;

    // Start from leftmost point, keep moving counterclockwise
    // until reach the start point again
    int p = l, q;
    do
    {
        // Search for a point 'q' such that orientation(p, i, q) is
        // counterclockwise for all points 'i'
        q = (p + 1) % n;
        for (int i = 0; i < n; i++)
            if (orientation(points[p], points[i], points[q]) == 2)
                q = i;

        count++;
        if(count > 110){
            break;
        }
 
        next[p] = q; // Add q to result as a next point of p
        p = q; // Set p as q for next iteration
    }
    while (p != l);

    int prev[n];
    FOR(i, 0, n){
        prev[i] = - 1;
    }
    FOR(i, 0, n){
        if(next[i]!=-1){
            prev[next[i]] = i;
        }
    }

    // 各点について
    FOR(i, 0, n){
        //凸包内なら確率が0より大きい可能性がある
        bool is_in_convex;
        if(next[i]==-1){
            is_in_convex = false;
        }else{
            is_in_convex = true;
        }

        if(is_in_convex){
            // 確率を出して、print
            // 点 i は凸包内
            // 凸包内での隣の点は？
            Point left = points[prev[i]];
            Point right = points[next[i]];
            Point center = points[i];
            printAngle(left, center, right);
        }
        else{
            p(0);
        }
    }
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);

    // input
    ll N;
    cin >> N;

    vector<Point> P;
    P.reserve(N);

    FOR(i, 0, N){
        ll x, y;
        cin >> x >> y;
        P.push_back(Point(x, y));
    }

    if(N==2){
        p(0.5);
        p(0.5);
    }
    // N > 3, 垂直二等分線が2本はある想定
    else{
        // 一直線チェック
        if(is_straight_line(P)){
            auto p = leftAndRight(P);
            int left_index = p.first;
            int right_index = p.second;
            
            // 端の2点だけ確率が0.5になる
            FOR(i, 0, N){
                if(i==left_index || i==right_index){
                    p(0.5);
                }else{
                    p(0);
                }
            }
        }
        else{
            // それ以外。convex hullを求める
            convexHull(P);
        }
    }
    
    return 0;
}

Measured memory_bytes: 256