#include <bits/stdc++.h>
/*
#include<algorithm>
#include<array>
#include<cassert>
#include<cmath>
#include<cstdlib>
#include<functional>
#include<iomanip>
#include<iostream>
#include<map>
#include<numeric>
#include<queue>
#include<set>
#include<stack>
#include<string>
#include<typeinfo>
#include<utility>
#include<vector>
*/
#define int long long int
#define double long double
using namespace std;
#define MOD 1000000007
#define INF 1000000000000000007
const int MAX_N = 1 << 17;
#define rep(i, n) for (int(i) = 0, i##_len = (n); (i) < i##_len; (i)++)
#define reps(i, x) for (int(i) = 1; (i) <= (int)(x); (i)++)
#define rrep(i, x) for (int(i) = ((int)(x)-1); (i) >= 0; (i)--)
#define rreps(i, x) for (int(i) = ((int)(x)); (i) > 0; (i)--)
#define FOR(i, a, b) for (int(i) = (a); (i) < (b); (i)++)
#define pb push_back
#define mp make_pair
#define bit(n) ((int)(1) << (n))
#define all(x) (x).begin(), (x).end()
#define debug(x) std::cout << #x << ": " << (x) << std::endl
#define nint int
using namespace std;

int dy[] = {0, 0, 1, -1, 0};
int dx[] = {1, -1, 0, 0, 0};
typedef pair<int, int> pii;
typedef pair<double, double> dop;
template <class T>
bool chmax(T& a, const T& b)
{
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <class T>
bool chmin(T& a, const T& b)
{
    if (b < a) {
        a = b;
        return 1;
    }
    return 0;
}
int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
struct aaa {
    aaa()
    {
        cin.tie(0);
        ios::sync_with_stdio(0);
        cout << fixed << setprecision(20);
    };
} aaaaaaa;
using namespace std;

struct Point {
    int x, y, num;
    bool operator<(const Point& p) const
    {
        return x < p.x || (x == p.x && y < p.y);
    }
};
int c_clockwise_delta(const Point& O, const Point& A, const Point& B)
{
    return (A.x - O.x) * (int)(B.y - O.y) - (A.y - O.y) * (int)(B.x - O.x);
}


/*
点群をソートした後,x軸の左側から時計回りになるように点を拾っていく
これによって(簡単のため凸包を円とすると)凸包の上半分が求まる.
次に点群を右から時計回りとなるように拾っていく.
先ほどとは異なり,右から左への遷移であるため先の上半分は反時計回りの点列である..
そのため今回拾うのは左から右への遷移では反時計回りである点列である.
これら2つの点列をつなげることによって凸包を構成することができる.
*/
vector<Point> convex_hull(vector<Point> P)
{
    int n = P.size(), k = 0;
    vector<Point> H(2 * n);
    sort(P.begin(), P.end());
    for (int i = 0; i < n; i++) {
        while (k >= 2 && c_clockwise_delta(H[k - 2], H[k - 1], P[i]) <= 0)
            k--;
        H[k++] = P[i];
    }
    for (int i = n - 2, t = k + 1; i >= 0; i--) {  //n-1を省いているのは,最右端が凸包に含まれるならすでに上半分に含まれているため
        while (k >= t && c_clockwise_delta(H[k - 2], H[k - 1], P[i]) <= 0)
            k--;
        H[k++] = P[i];
    }
    H.resize(k - 1);
    return H;
}
double cosier(double a)
{
    if (a > 1.0) {
        return 1.0;
    } else if (a < -1.0) {
        return -1.0;
    } else {
        return a;
    }
}

double rad(int ax, int ay, int bx, int by)
{
    int tri = ax * bx + ay * by;
    double absa = sqrt(ax * ax + ay * ay);
    double absb = sqrt(bx * bx + by * by);
    return acos(cosier((tri / absa) / absb)) / (2 * acos(-1));
}

signed main()
{
    int n;
    cin >> n;
    std::vector<Point> points;
    for (int i = 0; i < n; i++) {
        int x, y;
        cin >> x >> y;
        Point temp;
        temp.x = x;
        temp.y = y;
        temp.num = i;
        points.pb(temp);
    }
    std::vector<Point> ch = convex_hull(points);
    int chsize = ch.size();
    std::vector<double> out(n, 0);
    for (int i = 0; i < chsize; i++) {
        int tempx = -1 * (ch[(i + 1) % chsize].y - ch[i % chsize].y);
        int tempy = (ch[(i + 1) % chsize].x - ch[i % chsize].x);
        int lastx = -1 * (ch[i % chsize].y - ch[(i - 1 + chsize) % chsize].y);
        int lasty = (ch[i % chsize].x - ch[(i - 1 + chsize) % chsize].x);
        out[ch[i].num] = rad(tempx, tempy, lastx, lasty);
    }
    for (int i = 0; i < n; i++) {
        cout << out[i] << endl;
    }
    return 0;
}

Measured memory_bytes: 256