#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
#define int ll

#define REP(i,n) for(ll i=0;i<n;++i)
#define SORT(name) sort(name.begin(), name.end())
#define ZERO(p) memset(p, 0, sizeof(p))
#define MINUS(p) memset(p, -1, sizeof(p))
#if 0
#  define DBG(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#  define DBG(fmt, ...)
#endif

const ll LLINF = (1LL<<60);
const int INF = (1LL<<30);
const int MOD = 1000000007;
#define MAX_N 110

// --- 基本セット --- //
const double EPS = 1e-8;        // 非常に小さな値
const double PI = acos(-1);     // 円周率

// a == b なら true (誤差に寛容)
inline bool Eq(double a, double b) { return fabs(b - a) < EPS; }

// ユークリッド平面上の点を表す構造体
class Point
{
    public:
        double x, y;
    public:
        Point() {}
        Point(double x, double y) : x(x), y(y) {}
        Point operator+(const Point &b) const { return Point(x + b.x, y + b.y); }
        Point operator-(const Point &b) const { return Point(x - b.x, y - b.y); }
        Point operator*(const double b) const { return Point(x * b, y * b); }
        Point operator*(const Point &b) const { return Point(x * b.x - y * b.y, x * b.y + y * b.x); }

        Point operator/(const double b) const { return Point(x / b, y / b); }
        bool operator<(const Point &b) const { return x != b.x ? x < b.x : y < b.y; }
        bool operator==(const Point &b) const { return Eq(x, b.x) && Eq(y, b.y); }

        // 大きさの二乗を返します
        double Norm() { return x * x + y * y; }
        // 逆正接(y = 0 からの rad を [-π, π] の範囲で表したもの)を返します
        double Atan2() { return atan2(y, x); }
        // 大きさを返します
        double Abs() { return sqrt(Norm()); }
        // 原点を中心として反時計周りに theta (rad)度回転した座標を返します
        Point Rotate(double theta) { return Point(cos(theta) * x - sin(theta) * y, sin(theta) * x + cos(theta) * y); }
        // 原点を反時計周りに π/2 回転した座標を返します
        Point Rotate90() { return Point(-y, x); }
};

// 2 点の外積
double Cross(const Point &a, const Point &b) { return a.x * b.y - a.y * b.x; }
// 2 点の内積
double Dot(const Point &a, const Point &b) { return a.x * b.x + a.y * b.y; }
// ラジアンを角度に
double RadianToDegree(double r) { return (r * 180.0 / acos(-1)); }
// 角度をラジアンに
double DegreeToRadian(double d) { return (d * acos(-1) / 180.0); }
// a->b->c とたどったときの b の角度(ラジアン [0, π])
double GetAngle(const Point &a, const Point &b, const Point &c)
{
  const Point v = a - b, w = c - b;
  double alpha = atan2(v.y, v.x), beta = atan2(w.y, w.x);
  if(alpha > beta) { swap(alpha, beta); }
  double theta = (beta - alpha);
  return min(theta, 2 * acos(-1) - theta);
}

// 直線を表すクラス
class Line
{
    public:
        Point a, b;
    public:
        Line() {};
        Line(Point a, Point b) : a(a), b(b) {};
        // Ax + By = C という式が与えられたときの直線上の任意の 2 点を保存
        Line(double A, double B, double C)
        {
            if(Eq(A, 0)) { a = Point(0, C / B); b = Point(1, C / B); }
            else if(Eq(B, 0)) { a = Point(C / A, 0); b = Point(C / A, 1); }
            else { a = Point(0, C / B); b = Point(C / A, 0); }
        }
        // 傾きとの取得
        enum LineResult {
            INF_SLOPE,  // 傾き無限のグラフ (x = n のグラフ)
            NO_SLOPE,   // 切片のみのグラフ (y = b のグラフ)
            VALID_SLOPE // 傾きと切片のあるグラフ
        };
        // out_a に傾きが、 out_b に切片が、返り値として LineResult が返る
        // INF_SLOPE の時は out_b に x = n の n が入る
        int GetAB(double& out_a, double& out_b) {
            if(abs(a.x - b.x) < EPS) { return INF_SLOPE; }
            if(abs(a.y - b.y) < EPS) {
                out_b = a.y;
                return NO_SLOPE;
            }
            out_a = (a.y - b.y) / (a.x - b.x);
            out_b = a.y - out_a * a.x;
            return VALID_SLOPE;
        }
        // x 座標を渡した時に対応する y 座標を返します
        double GetY(double x) {
            double slope, intercept;
            // x = a の場合は適当な点を返す
            if(GetAB(slope, intercept) == INF_SLOPE) { return a.y; }
            return slope * x + intercept;
        }
        // y 座標を渡した時に対応する x 座標を返します
        double GetX(double y) {
            double slope, intercept;
            // y = b の場合は適当な点を返す
            if(GetAB(slope, intercept) == INF_SLOPE) { return a.x; }
            return (y - intercept) / slope;
        }
};

// 線分を表すクラス
// 直線と違い端点が定義できる場合はこちら
class Segment
{
    public:
        Point a, b;
        Segment() {};
        Segment(Point a, Point b) : a(a), b(b) {};
        // 中点を求める
        Point Center() { return Point((a.x + b.x) / 2, (a.y + b.y) / 2); }
        // 垂直二等分線を求める
        Line PerpBisector() {
            Point center = this->Center();
            return Line((a - center).Rotate90() + center, center);
        }
};

// 円を表すクラス
class Circle
{
    public:
        Point p;  // 中心
        double r; // 半径

        Circle() {};
        Circle(Point p, double r) : p(p), r(r) {};
};

// その他図形を表す型定義
typedef vector< Point > Polygon;            // 多角形
typedef vector< Segment > Segments;         // 線分集合
typedef vector< Line > Lines;               // 直線集合
typedef vector< Circle > Circles;           // 円集合
typedef pair< Point, Point > PointPoint;    // 2 点

// 点の進行方向を調べる
enum DotDir {
    Counterclockwise = 1,   // a -> b 反時計周りの方向に c
    Clockwise = -1,         // a -> b 時計周りの方向に c
    CAB = 2,                // c -> a -> b の順に並ぶ
    ABC = -2,               // a -> b -> c の順に並ぶ
    ACB = 0                 // a -> c -> b の順に並ぶ
};
// a -> b -> c の順に点をたどったときの進行方向 DotDir を返す
int Ccw(const Point &a, Point b, Point c)
{
  b = b - a, c = c - a;
  if(Cross(b, c) > EPS) { return Counterclockwise; }
  if(Cross(b, c) < -EPS) { return Clockwise; }
  if(Dot(b, c) < 0) { return CAB; }
  if(b.Norm() < c.Norm()) { return ABC; }
  return ACB;
}

// --- 基本セットここまで --- //

// --- 直線の平行・交差判定 --- //

// 直線の平行判定 a, b が平行なら true
bool Parallel(const Line& a,const Line& b){
  return abs(Cross(a.b - a.a, b.b - b.a)) < EPS;
}
// 直線の直交判定 a, b が直交していれば true
bool Orthogonal(const Line& a,const Line& b){
  return abs(Dot(a.a - a.b, b.a - b.b)) < EPS;
}

// --- 点から直線・線分への射影・反射 --- //
// ※射影と反射の定義、少し違う気がするが気にしないことにする

// 射影
// 点 p から直線 l に対して垂線をおろしたときの交点 x を射影と呼ぶことにする
// その x を返す
Point Projection(const Line& l, const Point& p) {
  double t = Dot(p - l.a, l.a - l.b) / (l.a - l.b).Norm();
  return l.a + (l.a - l.b) * t;
}
// 線分に対しても直線と同じ式()
Point Projection(const Segment& l, const Point& p) {
  double t = Dot(p - l.a, l.a - l.b) / (l.a - l.b).Norm();
  return l.a + (l.a - l.b) * t;
}

// 反射
// 直線 l を対象軸として点 p と線対称の位置にある点 x を p の反射と呼ぶ
Point Reflection(const Line& l, const Point& p) {
  return p + (Projection(l, p) - p) * 2.0;
}

// --- 点・直線・線分の距離 --- //

// いくつかの距離算出に交点を使うので前もって宣言
bool Intersect(const Line &l, const Point &p);
bool Intersect(const Line &l, const Line &m);
bool Intersect(const Segment &s, const Point &p);
bool Intersect(const Line &l, const Segment &s);
bool Intersect(const Segment &s, const Segment &t);
bool Intersect(const Circle &c, const Line &l);
bool Intersect(const Circle &c, const Point &p);
bool Intersect(const Circle &c1, const Circle& c2);
int Intersect(const Circle &c, const Segment &l);

// 2 点 a, b 間の距離
double Distance(const Point& a,const Point& b) { return (a - b).Abs(); }

// 点 p から直線 l に対して下した垂線の距離
// = 点 p と点 p の直線 l に対する射影の距離
double Distance(const Line& l,const Point& p) { return (p - Projection(l, p)).Abs(); }

// 直線同士の距離
// 平行である -> 直線 m 上の任意点からの l に対する射影への距離
// 平行でない -> 0
double Distance(const Line& l,const Line& m) {
  return Intersect(l, m) ? 0 : Distance(l, m.a);
}

// 線分と点の距離
// 点 p の線分 l に対する射影 r を求め、それが l 上にあるならそれと点 p の距離
// ないなら線分 l の両端のどっちか短い方が距離
double Distance(const Segment& s,const Point& p){
  Point r = Projection(s, p);
  if (Intersect(s, r)) { return (r - p).Abs(); }
  return min((s.a - p).Abs(), (s.b - p).Abs());
}

// 線分同士の距離
// 線分が交差している -> 0
// 交差していない -> 線分の端点の組み合わせパターンの最小が距離
double Distance(const Segment& a,const Segment& b){
  if(Intersect(a, b)) { return 0; }
  return min({ Distance(a, b.a), Distance(a, b.b), Distance(b, a.a), Distance(b, a.b) });
}

// 直線と線分の距離
// 交差している -> 0
// 交差していない -> 線分の端点 2 つと直線の距離の最小
double Distance(const Line& l,const Segment& s) {
  if (Intersect(l, s)) { return 0; }
  return min(Distance(l, s.a), Distance(l, s.b));
}

// --- 点・直線・線分の交差判定 --- //

// 直線 l 上に点 p があるなら true
bool Intersect(const Line &l, const Point &p) { return abs(Ccw(l.a, l.b, p)) != 1; }
// 直線同士が交わっているなら true
bool Intersect(const Line &l, const Line &m) {
  return abs(Cross(l.b - l.a, m.b - m.a)) > EPS || abs(Cross(l.b - l.a, m.b - l.a)) < EPS;
}
// 線分 s 上に点 p があるなら true
bool Intersect(const Segment &s, const Point &p) { return Ccw(s.a, s.b, p) == ACB; }
// 直線と線分が交わっているなら true
bool Intersect(const Line &l, const Segment &s) {
    return Cross(l.b - l.a, s.a - l.a) * Cross(l.b - l.a, s.b - l.a) < EPS;
}
// 線分同士が交わっているなら true
bool Intersect(const Segment &s, const Segment &t) {
  return Ccw(s.a, s.b, t.a) * Ccw(s.a, s.b, t.b) <= 0 && Ccw(t.a, t.b, s.a) * Ccw(t.a, t.b, s.b) <= 0;
}
// 直線と円が接しているなら true
bool Intersect(const Circle &c, const Line &l) { return Distance(l, c.p) <= c.r + EPS; }
// 点が円周上にあるなら true
bool Intersect(const Circle &c, const Point &p) { return abs((p - c.p).Abs() - c.r) < EPS; }
// 線分が円周と交差する数を返す
// ただし円の接線の場合も 2 を返す
int Intersect(const Circle &c, const Segment &l)
{
    // 円の中心から線分に向かっての射影までの距離が
    // 円の半径より大きいなら円と線分は交わっていない
    if((Projection(l, c.p) - c.p).Norm() - c.r * c.r > EPS) { return 0; }
    // 線分の端点から円の中心までの距離
    const double d1 = (c.p - l.a).Abs(), d2 = (c.p - l.b).Abs();
    // 両方の端点が円の内部にある場合は円に内包されているため交わっていない
    if(d1 < c.r + EPS && d2 < c.r + EPS) { return 0; }
    // 端点のどちらか片方だけ円に入っている
    if(d1 < c.r - EPS && d2 > c.r + EPS || d1 > c.r + EPS && d2 < c.r - EPS) { return 1; }
    // 円の中心から線分への射影
    const Point h = Projection(l, c.p);
    // 射影から各端点への内積が負 = 射影は線分の中にある
    // -> 線分は円を通過する
    if(Dot(l.a - h, l.b - h) < 0) { return 2; }
    return 0;
}

// 円周どうしの交差判定
bool Intersect(const Circle &c1, const Circle &c2) {
    double d = Distance(c1.p, c2.p);
    if(d > c1.r + c2.r) { return false; }
    if(d + min(c1.r, c2.r) < max(c1.r, c2.r)) { return false; }
    return true;
}


// 直線どうしの交点
// 交点があった場合は true を返し out に交点の値が入る
// 交点がなかった場合は false を返す
bool Crosspoint(Point& out, const Line &l, const Line &m)
{
    if(!Intersect(l, m)) { return false; }
    double A = Cross(l.b - l.a, m.b - m.a);
    double B = Cross(l.b - l.a, l.b - m.a);
    if(abs(A) < EPS && abs(B) < EPS) { out = m.a; }
    else { out = m.a + (m.b - m.a) * B / A; }
    return true;
}


// --- 凸包 --- //

// 凸包：与えられた点全てを包含する最小の凸多角形のこと
// 点集合を与えることで多角形を返す
// 点は x 方向最小の点から反時計周りで順番に格納される
// p のもともとの順番をソートにより破壊してしまうので注意
// O(N log N)
Polygon ConvexHull(Polygon& p){
  int n = p.size(), k = 0;
  if(n >= 3){
    sort(p.begin(), p.end());
    vector< Point > ch(2 * n);
    for(int i = 0; i < n; ch[k++] = p[i++]){
      while(k >= 2 && Cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < 0) { --k; }
    }
    for(int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--]){
      while(k >= t && Cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < 0) { --k; }
    }
    ch.resize(k - 1);
    return ch;
  } else {
    return p;
  }
}

// --- 点の多角形包含判定 --- //
enum
{
  Out, On, In
};
// 線上なら On, 多角形内なら In, それ以外なら Out が返る
int Contains(const Polygon &Q, const Point &p)
{
  bool in = false;
  for(int i = 0; i < Q.size(); i++) {
    Point a = Q[i] - p, b = Q[(i + 1) % Q.size()] - p;
    if(a.y > b.y) { swap(a, b); }
    if(a.y <= 0 && 0 < b.y && Cross(a, b) < 0) { in = !in; }
    if(Cross(a, b) == 0 && Dot(a, b) <= 0) { return On; }
  }
  return in ? In : Out;
}

// --- 多角形の重心 --- //

// 多角形の重心の位置を返す
Point GetPolyCenter(const Polygon& p) {
    Point ret(0, 0);
    for(auto& tmp_p : p) {
        ret.x += tmp_p.x;
        ret.y += tmp_p.y;
    }
    ret.x /= p.size();
    ret.y /= p.size();
    return ret;
}

// --- 多角形の法線 --- //

// 多角形の法線集合を求める
// Segment は a->b 方向に伸びるベクトルの法線であるとする
Segments GetNormal(const Polygon& p) {
    Segments res;
    for(int i = 0; i < p.size(); ++i) {
        Segment s = (i == p.size()-1) ? Segment(p[i], p[0]) : Segment(p[i], p[i+1]);
        Line pb = s.PerpBisector();     // 垂直二等分線
        // どれか垂直二等分線上の多角形外の点を探す
        for(int j = 0; j < 4; ++ j) {
            Point cand = s.Center();
            if(j == 0) {
                cand.x += 1.0;
                cand.y = pb.GetY(cand.x);
            }
            else if(j == 1) {
                cand.x -= 1.0;
                cand.y = pb.GetY(cand.x);
            }
            else if(j == 2) {
                cand.y += 1.0;
                cand.x = pb.GetX(cand.y);
            }
            else {
                cand.y -= 1.0;
                cand.x = pb.GetX(cand.y);
            }
            if(Contains(p, cand) == Out) {
                res.push_back(Segment(s.Center(), cand));
                break;
            }
            if(j == 3) { abort(); }
        }
    }
    return res;
}

// --- 凸多角形の各点から隣接点に延びる線分の垂直二等分線が成す角の角度 --- //

// 凸多角形の各点から 2 つの隣接点に向かって伸びる線分の
// 垂直二等分線によって形成される角の角度を求めます [0, π]
// p に対応したインデックスで vector で結果を返します
vector<double> GetPointAngle(const Polygon& ch) {
    vector<double> ret;
    REP(i, ch.size()) {
        // 前後の点 前：反時計回り方向で先にある点 後：時計回り方向で先にある点
        Point forward, back;
        if(i == 0) { forward = ch[i+1]; back = ch[ch.size()-1]; }
        else if(i == ch.size()-1) { forward = ch[0]; back = ch[i-1]; }
        else { forward = ch[i+1]; back = ch[i-1]; }
        Segment back_to_me(back, ch[i]), me_to_forward(ch[i], forward);
        // 直線の交点
        Point crossp;
        bool result = Crosspoint(crossp, back_to_me.PerpBisector(), me_to_forward.PerpBisector());
        if(!result) { ret.push_back(0); }   // 交点がない…角度 0 とする
        else {
            double ans_cand = GetAngle(back_to_me.Center(), crossp, me_to_forward.Center());
            double for_judge = GetAngle(back, ch[i], forward);
            if(for_judge < PI / 2 && Contains(ch, crossp) == Out) {
                ans_cand = PI - ans_cand;
            }
            ret.push_back(ans_cand);
        }
    }
    return ret;
}

ll N;
Polygon pol;
Polygon pol_for_ch;

ll PolToCh[MAX_N] = {};  // pol のインデックスを与えると対応する ch のインデックスを返す。ないときは -1

signed main()
{
    cin >> N;
    REP(i, N) {
        double a, b;
        cin >> a >> b;
        pol.push_back(Point(a, b));
        pol_for_ch.push_back(Point(a, b));
    }

    // 2 点しかない→両方 0.5
    if(N == 2) {
        REP(i, N) { printf("0.5\n"); }
        return 0;
    }
    // 全ての点が直線状にある→端点の 2 つが 0.5 を分け合う
    bool isAllXEq = true;
    bool isAllYEq = true;
    double min_x = pol[0].x;
    double max_x = pol[0].x;
    for(ll i = 0; i < N-1; ++i) {
        if(pol[i].x != pol[i+1].x) { isAllXEq = false; }
        if(pol[i].y != pol[i+1].y) { isAllYEq = false; }
    }
    if(isAllXEq) {
        double min_y = pol[0].y, max_y = pol[0].y;
        ll min_y_ind = 0, max_y_ind = 0;
        REP(i, N) {
            if(min_y > pol[i].y) {
                min_y = pol[i].y;
                min_y_ind = i;
            }
            if(max_y < pol[i].y) {
                max_y = pol[i].y;
                max_y_ind = i;
            }
        }
        REP(i, N) {
            if(i == max_y_ind || i == min_y_ind) { printf("0.5\n"); }
            else { printf("0\n"); }
        }
        return 0;
    }
    if(isAllYEq) {
        double min_x = pol[0].x, max_x = pol[0].x;
        ll min_x_ind = 0, max_x_ind = 0;
        REP(i, N) {
            if(min_x > pol[i].x) {
                min_x = pol[i].x;
                min_x_ind = i;
            }
            if(max_x < pol[i].x) {
                max_x = pol[i].x;
                max_x_ind = i;
            }
        }
        REP(i, N) {
            if(i == max_x_ind || i == min_x_ind) { printf("0.5\n"); }
            else { printf("0\n"); }
        }
        return 0;
    }

    // 凸包を求める
    // 凸包でない点 → 0
    Polygon ch = ConvexHull(pol_for_ch);

    // PolToCh の作成
    MINUS(PolToCh);
    REP(i, N) {
        REP(j, ch.size()) {
            if(pol[i] == ch[j]) {
                PolToCh[i] = j;
            }
        }
    }

    vector<double> ch_ans = GetPointAngle(ch);
    REP(i, N) {
        if(PolToCh[i] == -1) { printf("0\n"); }
        else {
            printf("%.10f\n", ch_ans[PolToCh[i]] / (2 * PI));
        }
    }

    return 0;
}


Measured memory_bytes: 640