AOJ - Problem 0010 : Circumscribed Circle of a Triangle

外接円の半径と外心を出力する問題です。
外接円と外心は高校生のときに習った記憶があります。
高校の教科書にも載っていると思います。
三角形が出てくるような幾何の問題では、正弦定理や余弦定理を使うことがあります。
外接円(wikipedia)
三角形クラスを作りました。まだ不完全ですが、内心や内接円の半径、直角三角形の判定などのメンバ関数
つくると、別の幾何の問題のときに使えるかもしれません。

#include <complex>
#include <cstdio>
#include <cmath>
using namespace std;

// 点座標を型とする
typedef complex<double> P;
// πの定義
#define PI 3.1415926535898

// 許容する誤差ε
#define EPS (1e-10)
//XY座標
#define X real()
#define Y imag()
	
// 三角形クラス
class Triangle{

private:
	//三角形の3点の座標
	P a, b, c;
	//三角形の3辺の長さ
	double edgeA,edgeB,edgeC;
	//三角形の3角の大きさ(ラジアン)
	double angleA,angleB,angleC;
	//余弦定理から3つの角度を求める関数
	double LawOfCosines(double a,double b, double c){
		return acos( (b*b+c*c-a*a) / (2.0*b*c) );
	}
	//2つのdouble型の数値が等しいかどうか
	bool equal(double a, double b){
		return (abs( a-b ) < EPS)? true : false ;
	}

public:
	//コンストラクタ(3つの点と辺と角度を初期化)
	Triangle(P p1, P p2, P p3){
		a = p1;
		b = p2;
		c = p3;
		edgeB = abs(c-a);
		edgeA = abs(b-c);
		edgeC = abs(a-b);
		angleA = LawOfCosines(edgeA,edgeB,edgeC);
		angleB = LawOfCosines(edgeB,edgeC,edgeA);
		angleC = LawOfCosines(edgeC,edgeA,edgeB);
	}
	
	double circumscribedCircleRadius(){//外接円の半径を返す
		return ( edgeA / sin(angleA) / 2.0 );
	}
	double circumscribedCircleX(){//外心(外接円の中心)のX座標を返す
		double A = sin(2.0*angleA);
		double B = sin(2.0*angleB);
		double C = sin(2.0*angleC);
		return ( (a.X * A + b.X * B + c.X * C) / (A+B+C) );
	}
	double circumscribedCircleY(){//外心(外接円の中心)のY座標を返す
		double A = sin(2.0*angleA);
		double B = sin(2.0*angleB);
		double C = sin(2.0*angleC);
		return ( (a.Y * A + b.Y * B + c.Y * C) / (A+B+C) );
	}
};

int main(){
	int n;
	double x1, x2, x3, y1, y2, y3;
	double r, xp, yp;

	scanf("%d", &n);
	for (int i=0 ; i<n ; i++){
		scanf("%lf %lf %lf %lf %lf %lf", &x1, &y1, &x2, &y2, &x3, &y3);
		P a( x1 , y1 );
		P b( x2 , y2 );
		P c( x3 , y3 );
		Triangle Tr(a,b,c);
		r  = Tr.circumscribedCircleRadius();
		xp = Tr.circumscribedCircleX();
		yp = Tr.circumscribedCircleY();
		printf("%.3f %.3f %.3f\n", xp,yp,r);
	}
}