#include <stdio.h>
#include <eggx.h>

// ============================ EGGX

int win;

#define WW (600)
#define HH (600)


// ========================== 二線分の交差チェック
/*
 http://www.hiramine.com/programming/graphics/2d_segmentintersection.html
 を参考に。
 線分 AB (ax,ay)-(bx,by) と CD (cx,cy)-(dx,dy) が交差しているかどうかを調べる
 r, s が共に 0-1 の間にあれば衝突と判定
 ただし、
 戻り値は衝突時は r そのもの。範囲は 0.0 <= r <= 1.0 である。
 非衝突時は 9.0 を返す。
 ただし、二線分が並行な場合は 99.0 であり、
 二線分が同一（重なっている）の場合は 999.0 を返す
 この r を用いて交差座標位置を求める
 */

#define NOCROSS  9.0
#define PARALLEL 99.0
#define DOUBLE   999.0

float colCheck(float ax, float ay,
			   float bx, float by,
			   float cx, float cy,
			   float dx, float dy)
{
	float denom; // 途中計算における分母(denominator)
	float acx, acy; // ベクター AC を表現する
	float r, s;
	
	denom = (bx - ax) * (dy - cy) - (by - ay) * (dx - cx);
	if( denom == 0.0 ) return PARALLEL; // 二線は並行である

	// ベクター AC を得る（C - A にあたる） 
	acx = cx - ax; acy = cy - ay;
	
	r=( ( dy - cy ) * acx - ( dx - cx ) * acy ) / denom;
	s=( ( by - ay ) * acx - ( bx - ax ) * acy ) / denom;
	
	if( (r == 0.0)&&(s == 0.0)) return DOUBLE; // 二線は同一である
	
	if( (0.0 <= r) && (r <= 1.0) && (0.0 <= s) && (s <= 1.0)) {
		return r; // 交差した
	} else {
		return NOCROSS; // 交差しない
	}
		
}

void setup(void)
{
	win=gopen(WW, HH);
	winname(win, "Collision test");
	
}

void closeall(void)
{
	ggetch();
	gclose(win);
}

int main (int argc, const char * argv[]) {
	float r, ax, ay, bx, by, cx, cy, dx, dy;
	float isx, isy;
	
	setup();
	
	ax=100.0; ay=100.0;
	bx=200.0; by=200.0;
	cx=200.0; cy=100.0;
	dx=100.0; dy=200.0;

	
	newpen(win, 1);
	drawline(win, ax, ay, bx, by);
	newpen(win, 2);
	drawline(win, cx, cy, dx, dy);

	// fillrect(win,10,100,380,10);
	
	r=colCheck(ax, ay, bx, by, cx, cy, dx, dy);
	if(r >= NOCROSS) { // 交差しなかった
		drawstr(win, 10.0, 10.0, 16, 0.0, "NO CROSS");
	} else { // 交差した
		// 交差点を AB から求める（A から r ぶんだけ AB 方向に進んだ位置）
		isx = ax + r * ( bx - ax );
		isy = ay + r * ( by - ay );
	}
	
	newpen(win, 3);
	drawcirc(win, isx, isy, 3.0, 3.0);
	
	closeall();
    return 0;
}
