#include <algorithm>
#include <iostream>
#include <cstdio>
#include <vector>
#include <cmath>
#include <complex>
using namespace std;

typedef complex<double> point;
typedef vector<point> poly;

#define EPSILON (1e-7)

bool is_negative(double x) { return x < -EPSILON; } 
bool is_zero(double x) { return abs(x) <= EPSILON; }
bool is_positive(double x) { return x > EPSILON; }
double cross_product(const point &A, const point &B) { return real(A) * imag(B) - real(B) * imag(A); }
double twice_signed_poly_area(const poly &V) { double res = 0; for (unsigned i=0; i<V.size(); i++) res += cross_product( V[i], V[(i+1)%V.size()] ); return res; }
double poly_area(const poly &V) { return abs(0.5 * twice_signed_poly_area(V)); }
point rotate_point(const point &bod, const point &stred, double uhol) { point mul(cos(uhol),sin(uhol)); return ((bod-stred)*mul)+stred; }
poly rotate_poly(poly V, const point &stred, double uhol) { for (unsigned i=0; i<V.size(); i++) V[i] = rotate_point(V[i],stred,uhol); return V; }

// rotate and translate P to align edge #edge_id onto the x axis
vector<point> align_edge(const vector<point> &P, int edge_id) {
  int N = P.size();
  point cur = P[edge_id], next = P[(edge_id+1)%N];
  double angle = atan2( imag(next)-imag(cur), real(next)-real(cur) );
  poly Q = rotate_poly(P,cur,-angle);
  for (int i=0; i<N; ++i) Q[i] -= cur;
  return Q;
}

// find the x of the unique point (x,y) on the non-horizontal segment AB
double interpolate(const point &A, const point &B, double y) {
  double x1 = real(A), y1 = imag(A), x2 = real(B), y2 = imag(B);
  double fraction = (y-y1)/(y2-y1);
  return x1 + fraction*(x2-x1);
}

// compute the integral over the part of P which lies above the x axis
double process_top(const vector<point> &P) {
  double result = 0;
  int N = P.size();

  // make horizontal cuts through all vertices
  vector<double> cuts;
  for (int i=0; i<N; ++i) if (!is_negative(imag(P[i]))) cuts.push_back( imag(P[i]) );
  sort( cuts.begin(), cuts.end() );
  int C = cuts.size();

  // for each horizontal strip
  for (int i=0; i<C-1; ++i) {
    double lo = cuts[i], hi = cuts[i+1];
    if (is_zero(hi-lo)) continue;

    // find all edges that intersect it and order them left to right
    vector< pair<double,int> > edges;
    for (int j=0; j<N; ++j) {
      point cur = P[j], next = P[(j+1)%N];
      bool push = false;
      if (!is_positive(imag(cur)-lo) && !is_negative(imag(next)-hi)) push = true;
      if (!is_positive(imag(next)-lo) && !is_negative(imag(cur)-hi)) push = true;
      if (push) edges.push_back( make_pair(interpolate(cur,next,(lo+hi)/2), j) );
    }
    sort(edges.begin(), edges.end() );

    // compute the integrals in the parts between succesive edges
    double A = 0, B = 0, S = edges.size();
    int sign = -1;
    for (int i=0; i<S; ++i) { A += sign * interpolate( P[edges[i].second], P[(edges[i].second+1)%N], lo ); sign *= -1; }
    sign = -1;
    for (int i=0; i<S; ++i) { B += sign * interpolate( P[edges[i].second], P[(edges[i].second+1)%N], hi ); sign *= -1; }
    double P = (B-A)/(hi-lo);
    double Q = (hi*A - lo*B)/(hi-lo);
    result += P/3*(hi*hi*hi-lo*lo*lo) + Q/2*(hi*hi-lo*lo);
  }
  return result;
}

int main() {
  int T;
  cin >> T;
  while (T--) {
    int N;
    poly P;
    cin >> N;
    for (int n=0; n<N; ++n) { double x,y; cin >> x >> y; P.push_back(point(x,y)); }

    double result = 0;
    for (int n=0; n<N; ++n) {
      poly Q = align_edge(P,n);
      double current = process_top(Q);
      for (int i=0; i<N; ++i) Q[i] = point( real(Q[i]), -imag(Q[i]) );
      current += process_top(Q);
      current /= poly_area(Q);
      result += current;
    }
    printf("%.12f\n",result);
  }
}
// vim: fdm=marker:commentstring=\ \"\ %s:nowrap:autoread
