#include "geom.h"
#include "hash.h"

int cirNcir2line( const Circle* c1, const Circle* c2, Line* l){
float B;

	if( !c1 || !c2 || !l )
		return E_BADINPUT;

	B = c1->C.X - c2->C.X;
	if( !B )
		return E_NORESULT;

	l->M = ( c1->C.Y - c2->C.Y ) / B;
	l->K = ( c2->R*c2->R - c1->R*c1->R + 
		c1->C.X*c1->C.X - c2->C.X*c2->C.X +
		c1->C.Y*c1->C.Y - c2->C.Y*c2->C.Y ) / 
		( 2. * B );

return 0;
}

int lineNline2point( const Line* l1, const Line* l2, Point* p){
	
	if( !l1 || !l2 || !p )
		return E_BADINPUT;

	if( l1->M == l2->M )
		return E_NORESULT;

	p->Y = ( l1->K - l2->K ) / ( l1->M - l2->M );
	p->X = l1->K - p->Y * l2->M; 

return 0;
}

int lineNpoint2R2( const Line* l, const Point* p, float* r2){
float Y;

	if( !l || !p || !r2 )
		return E_BADINPUT;

	if( !l->M )
		return E_NORESULT;

	Y = (l->K + l->M * p->Y - p->X ) / (2. * l->M);
	*r2 = ( 1. / (l->M*l->M) + 1. ) * ( p->Y - Y ) * ( p->Y - Y );

return 0;
}

int triangulate( const Circle* c1, const Circle* c2, const Circle* c3, Point* p){
int stat;
Line l1, l2, l3;
Point p1, p2, p3;

	if( !c1 || !c2 || !c3 || !p )
		return E_BADINPUT;

	if( (stat = cirNcir2line( c1, c2, &l1 )) )
		return stat;

	if( (stat = cirNcir2line( c2, c3, &l2 )) )
                return stat;
	
	if( (stat = cirNcir2line( c3, c1, &l3 )) )
                return stat;

	if( (stat = lineNline2point( &l1, &l2, &p1 )) )
                return stat;

	if( (stat = lineNline2point( &l2, &l3, &p2 )) )
                return stat;

	if( (stat = lineNline2point( &l2, &l3, &p3 )) )
                return stat;

	p->X = ( p1.X + p2.X + p3.X ) / 3.;
	p->Y = ( p1.Y + p2.Y + p3.Y ) / 3.;

return 0;
}

