Problem: There is a flat island whose shape is a perfect square. On this island, there are three habitants whose names are IC, PC, and ACM Every day, one jewel is dropped from the heaven. Just as the jewel touches the ground, IC, PC, and ACM leave their houses simultaneously, run with the same speed, and then a person who first touched the jewel can get the jewel. Hence, the person whose house is nearest to the location of the jewel is the winner of that day.

They always have a quarrel with each other, and therefore their houses are located at distinct places. The locations of their houses are fixed. This jewel falls at a random point on the island, that is, all points on the island have even chance.

When three are two or more persons whose houses are simultaneously nearest, the last person in the order of

IC, PC, ACM

obtains the jewel.

Our interest is to know the probability for IC to get the jewel under this situation.



Input

The input describes one problem instance per line. Each line contains the x- and y-coordinates of IC's home, those of PC's, and those of ACM's in this order. Note that the houses of IC, PC and ACM are located at distinct places. The end of the input is indicated by a line with six zeros.

The coordinates of the whole island are given by (0, 10000) × (0, 10000) and coordinates of houses are given in integer numbers between 1 and 9999, inclusive. It should be noted that the locations of the jewels are arbitrary places on the island and their coordinate values are not necessarily integers.

Output

For each input line, your program should output its sequence number starting from 1, and the probability for the instance. The computed probability values should have errors less than 10-5.

The sequence number and the probability should be printed on the same line. The two numbers should be separated by a space.

Example

Input

2000 2000 8000 8000 9000 9500
2500 2500 7500 2500 2500 7500
0 0 0 0 0 0


Output

1 0.50000
2 0.25000

Solution (in CPP):

Solution:
#include <cstdio>
#include <iostream>
#include <vector>
#include <list>
#include <cmath>
#include <fstream>
#include <algorithm>
#include <string>
#include <queue>
#include <set>
#include <map>
#include <complex>
#include <iterator>
#include <cstdlib>
#include <cstring>
#include <sstream>

using namespace std;

#define EPS (1e-10)
#define EQ(a,b) (abs((a) - (b)) < EPS)
#define EQV(a,b) (EQ((a).real(),(b).real()) && EQ((a).imag(),(b).imag()))

typedef complex<double> P;
typedef pair<P,P> Edge;
typedef long long ll;

const double PI=4*atan(1.0);
const int MAX_SIZE = 10000;

// 内積
double dot(P a, P b) {
  return (a.real() * b.real() + a.imag() * b.imag());
}
// 外積
double cross(P a, P b) {
  return (a.real() * b.imag() - a.imag() * b.real());
}
// 点cが直線ab上にあるかないか
int is_point_on_line(P a, P b, P c) {
  return EQ( cross(b-a, c-a), 0.0 );
}
// 2直線の直行判定
int is_orthogonal(P a1, P a2, P b1, P b2) {
  return EQ( dot(a1-a2, b1-b2), 0.0 );
}
// 2直線の平行判定
int is_parallel(P a1, P a2, P b1, P b2) {
  return EQ( cross(a1-a2, b1-b2), 0.0 );
}
// 点a,bを通る直線と点cの間の距離
double distance_l_p(P a, P b, P c) {
  return abs(cross(b-a, c-a)) / abs(b-a);
}
// 点a,bを端点とする線分と点cとの距離
double distance_ls_p(P a, P b, P c) {
  if ( dot(b-a, c-a) < EPS ) return abs(c-a);
  if ( dot(a-b, c-b) < EPS ) return abs(c-b);
  return abs(cross(b-a, c-a)) / abs(b-a);
}
// 点が多角形の中に存在するかどうか
bool isInPolygon(vector<P> &points,P s){
	if(points.size()==1)return false;
	vector<P> v;
	for(int i=0;i<(int)points.size();i++)v.push_back(points[i]-s);
	int sign=0;
	for(int i=1;i<=(int)v.size();i++){
		int prv=(i-1+v.size())%v.size();
		int cur=i%v.size();
		double c=cross(v[prv],v[cur]);
		if(EQ(c,0))continue;
		else if(sign==0){
			if(c>0)sign=1;
			else sign=-1;
		}
		else{
			if(sign==-1&&c>0)return false;
			else if(sign==1&&c<0)return false;
		}
	}
	return true;
}
struct Rec{
	vector<P> p;
};
// a1,a2を端点とする線分とb1,b2を端点とする線分の交差判定
int is_intersected_ls(P a1, P a2, P b1, P b2) {
    // 線分が平行な場合は重なっていないことにする
    if(abs(cross(a2-a1,b2-b1)) < EPS){
        return 0;
    }
    return ( cross(a2-a1, b1-a1) * cross(a2-a1, b2-a1) < EPS ) &&
        ( cross(b2-b1, a1-b1) * cross(b2-b1, a2-b1) < EPS );
}
// aとbの矩形が接しているかどうか(どちらかがどちからを含んでいるものもふくむ
bool isTouchRectangle(Rec &a,Rec &b){
	// aの各頂点がbの中に存在しているかチェック
	for(int i=0;i<4;i++)if(isInPolygon(b.p,a.p[i]))return true;
	// 逆
	for(int i=0;i<4;i++)if(isInPolygon(a.p,b.p[i]))return true;
	// 各辺が他方のどれかの辺と接しているか
	for(int i=0;i<4;i++){
		int curi=i;
		int prvi=(i-1+4)%4;
		for(int j=0;j<4;j++){
			int curj=j;
			int prvj=(j-1+4)%4;
			if(is_intersected_ls(a.p[curi],a.p[prvi],b.p[curj],b.p[prvj]))return true;
		}
	}
	return false;
}
// a1,a2を端点とする線分とb1,b2を端点とする線分の交点計算
P intersection_ls(P a1, P a2, P b1, P b2) {
  P b = b2-b1;
  double d1 = abs(cross(b, a1-b1));
  double d2 = abs(cross(b, a2-b1));
  double t = d1 / (d1 + d2);

  return a1 + (a2-a1) * t;
}
// a1,a2を通る直線とb1,b2を通る直線の交差判定
int is_intersected_l(P a1, P a2, P b1, P b2) {
  return !EQ( cross(a1-a2, b1-b2), 0.0 );
}
// a1,a2を通る直線とb1,b2を通る直線の交点計算
P intersection_l(P a1, P a2, P b1, P b2) {
  P a = a2 - a1; P b = b2 - b1;
  return a1 + a * cross(b, b1-a1) / cross(b, a);
}
// 単位ベクトルを求める
P normalVector(P p){
	return p/abs(p);
}
// 法線ベクトルを求める
P unitVector(P a){
	return P(-a.imag(),a.real());
}
// 単位法線ベクトルを求める
P unitNormalVector(P tmp){
	P e=P(-tmp.imag(),tmp.real());
	e/=abs(e);
	return e;
}
// 座標の回転(座標pにある点を,半時計回りにa(ラジアン)回転)
P roundPoint(P p,double a){
	return P(cos(a)*p.real()-sin(a)*p.imag(),sin(a)*p.real()+cos(a)*p.imag());
}
/*
円周と線分の交差判定
*/
bool isCircleCrossLine(P a,P b,P c,double r){
	double d1 = abs(a-c);
	double d2 = abs(b-c);
    // 線分が中に含まれるとき、ここのコメントアウトをはずせばtrue(交差)となる
	//if(d1<r&&d2<r)
	//	return true;
	double d = distance_ls_p(a,b,c);
	return (EQ(d,r)||d<r);
}
// 三角形の内部に点があるかどうか
// 外積の正負がすべて同じなら内部に点あり
bool isInTriangle(P p1,P p2,P p3,P s){
	P a=p1-s;
	P b=p2-s;
	P c=p3-s;
	return ((cross(a,b)>0&&cross(b,c)>0&&cross(c,a)>0)||(cross(a,b)<0&&cross(b,c)<0&&cross(c,a)<0));
}
// 矩形の中に点が存在するかどうか
bool isInRectangle(P p1,P p2,P p3,P p4,P s){
	P a=p1-s;
	P b=p2-s;
	P c=p3-s;
    P d=p4-s;
	return ((cross(a,b)>0&&cross(b,c)>0&&cross(c,d)>0&&cross(d,a)>0)
        ||(cross(a,b)<0&&cross(b,c)<0&&cross(c,d)<0&&cross(d,a)<0));
}
// 三角形の面積を座標から計算
double calcAreaOfTriangle(P a,P b,P c){
	return abs((b.real()-a.real())*(c.imag()-a.imag()) - (c.real()-a.real())*(b.imag()-a.imag()))/2;
}
// 与えられた円の範囲内に点が存在するかどうか
bool isContainingDot(P c,double r,P a){
	return (((c.real()-a.real())*(c.real()-a.real())
		+(c.imag()-a.imag())*(c.imag()-a.imag())<r*r)
		||EQ((c.real()-a.real())*(c.real()-a.real())
		+(c.imag()-a.imag())*(c.imag()-a.imag()),r*r));
}
// 多角形の面積公式
double calcPolygonArea(vector<P> p){
  double sum=0;
  for(int i = 0; i < p.size(); i++)
    sum+=cross(p[i],p[(i+1)%(p.size())]);
  return sum/2;
}
// 2ベクトル間の角度
// aからbへ左周りで何度か(0->2*PI)
double diffAngle(P a,P b){
    double angle=atan2(cross(a,b),dot(a,b));
    if(angle<0)
        return 2*PI+angle;
    return angle;
}
// 2つのベクトルの重なっている部分の長さを返す
// もし重なっていなければ0を返す
double multipleLength(P a,P b,P c,P d){
    Edge e1=make_pair(a,b);
    Edge e2=make_pair(c,d);
    // 平行であるかどうか
    if(!(is_parallel(e1.first,e2.first,e1.second,e2.second)
        &&is_parallel(e1.first,e1.second,e2.first,e2.second)))
        return 0;
    double dist=0;
    // 両方乗っている
    if(EQ(distance_ls_p(e1.first,e1.second,e2.first),0)&&EQ(distance_ls_p(e1.first,e1.second,e2.second),0))
        dist=abs(e2.first-e2.second);
    else if(EQ(distance_ls_p(e2.first,e2.second,e1.first),0)&&EQ(distance_ls_p(e2.first,e2.second,e1.second),0))
        dist=abs(e1.first-e1.second);
    else if(EQ(distance_ls_p(e1.first,e1.second,e2.first),0)){
        // どちらが線上にあるか
        if(EQ(distance_ls_p(e2.first,e2.second,e1.first),0))
            dist=abs(e1.first-e2.first);
        else
            dist=abs(e1.second-e2.first);
    }
    else if(EQ(distance_ls_p(e1.first,e1.second,e2.second),0)){
        if(EQ(distance_ls_p(e2.first,e2.second,e1.first),0))
            dist=abs(e1.first-e2.second);
        else
            dist=abs(e1.second-e2.second);
    }
    return dist;
}
// 2点を通る半径rの円の中点を求める
pair<P,P> calcCircleCenterPoint(P dot1,P dot2,double r){
    double v=abs(dot1-dot2);
    double x = sqrt(r*r - (v/2)*(v/2));
    // 二組の単位法線ベクトル
    P hose[2];
    double x1=-(dot1.imag()-dot2.imag());
    double y1=(dot1.real() - dot2.real());
    hose[0]=P(x1,y1);
    double y2=-y1;
    double x2=-x1;
    hose[1]=P(x2,y2);
    double dd1=abs(hose[0]);
    double dd2=abs(hose[1]);
    hose[0]/=dd1;hose[0]*=x;
    hose[1]/=dd2;hose[1]*=x;
    P tmp=(dot1+dot2);
    tmp/=2;
    hose[0]+=tmp;
    hose[1]+=tmp;
    return make_pair(hose[0],hose[1]);
}
// 4線分が端点以外でクロスしているかどうかを判定
bool checkCross(const vector<Edge> &vec){
    for(int i=0;i<vec.size();i++){
        for(int j=i+1;j<vec.size();j++){
            // 線分がクロスしているかどうか
            if(is_intersected_ls(vec[i].first,vec[i].second,vec[j].first,vec[j].second)){
                // している場合、端点以外でクロスしているなら、false
                P p=intersection_ls(vec[i].first,vec[i].second,vec[j].first,vec[j].second);
                if(!(EQ(p,vec[i].first)||EQ(p,vec[i].second)))
                    return false;
            }
        }
    }
    return true;
}
// 引き数で与えられた4つの点が矩形を作るどうかを判定
bool checkRec(const vector<P> &squ){
    vector<int> v;
    for(int i=0;i<squ.size();i++)v.push_back(i);
    do{
        vector<Edge> ve;
        for(int i=0;i<4;i++)
            ve.push_back(make_pair(squ[v[i]],squ[v[(i+1)%4]]));
        // ここですべての線分がクロスするかどうかを計算
        if(checkCross(ve)){
            // 線分の長さを確認
            if(EQ(abs(ve[0].first-ve[0].second),abs(ve[2].first-ve[2].second)))
                if(EQ(abs(ve[1].first-ve[1].second),abs(ve[3].first-ve[3].second)))
                    // 直行
                    if(is_orthogonal(ve[0].first,ve[0].second,ve[1].first,ve[1].second))
                        if(is_orthogonal(ve[2].first,ve[2].second,ve[3].first,ve[3].second))
                        return true;
        }
    }while(next_permutation(v.begin(),v.end()));
    return false;
}
// 引き数で与えられた4つの点が正方形を作るかどうかを判定
bool checkSqu(const vector<P> &squ){
    vector<int> v;
    for(int i=0;i<squ.size();i++)v.push_back(i);
    do{
        vector<Edge> ve;
        for(int i=0;i<4;i++)
            ve.push_back(make_pair(squ[v[i]],squ[v[(i+1)%4]]));
        // ここですべての線分がクロスするかどうかを計算
        if(checkCross(ve)){
            // 線分の長さを確認
            double d=abs(ve[0].first-ve[0].second);
            for(int i=1;i<4;i++){
                double d2=abs(ve[i].first-ve[i].second);
                if(!EQ(d,d2))return false;
            }
            // 直行確認
            if(is_orthogonal(ve[0].first,ve[0].second,ve[1].first,ve[1].second))
                if(is_orthogonal(ve[2].first,ve[2].second,ve[3].first,ve[3].second))
                    return true;
        }
    }while(next_permutation(v.begin(),v.end()));
    return false;
}
// 二円の共通接線を構成する4直線を求める(二円はお互い接したりどちらかをふくんだりしない)
vector<pair<P,P> > calcCommonTangentialLine(P p1,double r1,P p2,double r2){
	vector<pair<P,P> > res;
	if(r1>r2){
		swap(r1,r2);
		swap(p1,p2);
	}
	// 共通外接線
	{
		double d=abs(p1-p2);
		double a=abs(r1-r2);
		double b=sqrt(d*d-a*a);
		double sita=acos(b/d);
		P e=normalVector(roundPoint((roundPoint((p2-p1),sita)),PI/2));
		res.push_back(make_pair(e*r1+p1,e*r2+p2));
		P e2=normalVector(roundPoint((roundPoint((p2-p1),-sita)),-PI/2));
		res.push_back(make_pair(e2*r1+p1,e2*r2+p2));
	}
	// 共通内接線
	{
		P cp=(r1*p1+r2*p2)/(r1+r2);
		double u=abs(cp-p1);
		double sita=acos(r1/u);
		P e=normalVector(roundPoint(cp-p1,sita));
		res.push_back(make_pair(e*r1+p1,-e*r2+p2));
		P e2=normalVector(roundPoint(cp-p1,-sita));
		res.push_back(make_pair(e2*r1+p1,-e2*r2+p2));
	}
	return res;
}
/*
  与えられた3点a,b,c,をa->b->cと進むとき
  a->bで時計方向に折れて,b->c
  a->bで半時計方向に折れて,b->c
  a->bで逆を向いてaを通り越してb->c
  a->bでそのままb->c
  a->bで逆を向いてb->c
  のどれであるかを判定
*/
int ccw(P a,P b, P c){
  b-=a;c-=a;
  if(cross(b,c)>0&&!EQ(cross(b,c),0))return 1;// counter clockwise
  if(cross(b,c)<0&&!EQ(cross(b,c),0))return -1;// clockwise
  if(dot(b,c)<0&&!EQ(dot(b,c),0))return 2; // c-a-b on line
  if(!EQ(abs(b),abs(c))&&abs(b)<abs(c))return -2; // a-b-c on line
  return 0;
}
// 凸多角形の切断を行う
// lineのfirst側から見て左の多角形が返る
// 多角形は上が+y,右が+xの座標系で座標を時計周りに格納したvectorで表す
// lineは基本的にmakeDivisorで作成
vector<P> convex_cut(vector<P> polygon,pair<P,P> line){
  vector<P> resPolygon;
  int n=polygon.size();
  for(int i=0;i<n;i++){
    P A=polygon[i];
    P B=polygon[(i+1)%n];
    if(ccw(line.first,line.second,A)!=-1)
      resPolygon.push_back(A);
    if(ccw(line.first,line.second,A)*ccw(line.first,line.second,B)<0)
      resPolygon.push_back(intersection_l(A,B,line.first,line.second));
  }
  return resPolygon;
}
// convex_cutの補助関数
// a側の凸多角形を残すような切断ラインを作成
pair<P,P> makeDivisor(P a, P b){
  P mid=(a+b);mid/=2;
  P base=unitNormalVector(b-a);
  base*=-1000000;
  P p1=base;p1+=mid;
  base*=-1;
  P p2=base;p2+=mid;
  return make_pair(p1,p2);
}

P ps[3];
int xs[3];
int ys[3];

int main(){
  int cnt=1;
  while(cin>>xs[0]>>ys[0]>>xs[1]>>ys[1]>>xs[2]>>ys[2]&&(xs[0]|xs[1]|xs[2]|ys[0]|ys[1]|ys[2])){
    for(int i=0;i<3;i++)ps[i]=P(xs[i],ys[i]);
    vector<P> init;
    init.push_back(P(0,0));init.push_back(P(0,10000));
    init.push_back(P(10000,10000));init.push_back(P(10000,0));
    init=convex_cut(init,makeDivisor(ps[0],ps[1]));
    init=convex_cut(init,makeDivisor(ps[0],ps[2]));
    double S=abs(calcPolygonArea(init));
    printf("%d %.10f\n",cnt,S/100000000);
    cnt++;
  }

  return 0;
}