// 처음 두 원이 접하지도 교차하지도 않은 상태를 가정함.

#include <cmath>
#include <cstdio>
#include <stack>

#define PI 3.14159

// x,y 좌표
class POINT
{
protected:
	float x;
	float y;

public:
	POINT(float _x, float _y)
		:x(_x), y(_y)
	{

	}
};

// 원
class CIRCLE : public POINT
{
private:
	float r;
	float d;
	float seta;

public:
	CIRCLE(float _x, float _y, float _r, float _d, float _seta)
		:POINT(_x,_y), r(_r), d(_d), seta(_seta/PI)
	{
		puts("생성 & 초기화 성공 ");
	}
	// second*d로 움직인 이후의 x,y
	void MovePerSecond(const float second)
	{
		float old_x = x;
		float old_y = y;
		x = x + d * second * cos(seta);
		y = y + d * second * sin(seta);
		printf("(%.2f,%.2f) -> (%.2f,%.2f)\n", old_x, old_y, x, y);
	}

	float DistanceBetweenTwoCircle(const CIRCLE& c)
	{
		return sqrt(pow(this->x - c.x, 2) + pow(this->y - c.y, 2));
	}

	void CalculateIntersectPosition(const CIRCLE& c)
	{

		float sum_r = this->r + c.r;
		float point_x = this->x*(this->r / sum_r) + c.x*(c.r / sum_r);
		float point_y = this->y*(this->r / sum_r) + c.y*(c.r / sum_r);

		printf("충돌 좌표 : (%.2f, %.2f) \n", point_x, point_y);
	}

	float GetRadius()
	{
		return this->r;
	}
};

class TestCollision
{
private:
	CIRCLE* c1;
	CIRCLE* c2;

public:
	TestCollision(const CIRCLE& _c1, const CIRCLE& _c2)
	{
		c1 = new CIRCLE(_c1);
		c2 = new CIRCLE(_c2);
	}

	~TestCollision()
	{
		delete c1;
		delete c2;
	}

	// 두 원 사이의 거리
	float DistanceBetweenTwoCircle()
	{
		return c1->DistanceBetweenTwoCircle(*c2);
	}
	// 두 원의 접점의 좌표.
	void CalculateIntersectPosition()
	{
		c1->CalculateIntersectPosition(*c2);
	}
	// 두 원이 충돌하는지 second를 증가시키면서 테스트
	void IsCollision(float second)
	{
		float c1_radius = c1->GetRadius();
		float c2_radius = c2->GetRadius();

		std::stack<float> s;
		float distance = DistanceBetweenTwoCircle();
		s.push(distance);

		while (true)
		{
			c1->MovePerSecond(second);
			c2->MovePerSecond(second);
			distance = DistanceBetweenTwoCircle();

			if (distance <= c1_radius + c2_radius)
			{
				puts("충돌 발생 ");
				CalculateIntersectPosition();
				break;
			}
			else
			{
				printf("충돌 안함 거리 %f \n",distance);
				second += 0.1;
				
				// 충돌이 계속 안하는 경우에는, 방금 전의 distance가 지금보다 짧다면 그게 가장 가까운 것.
				if (s.top() < distance)
				{
					printf("%f가 가장 가까운 거리\n", s.top());
					break;
				}
				else
				{
					s.push(distance);
				}
			}
		}
	}
};

int main()
{
	CIRCLE c1(10.0f, 10.0f, 5.0f, 6.0f, 60.0f);
	CIRCLE c2(20.0f, 20.0f, 5.0f, 5.0f, 60.0f);

	TestCollision t(c1, c2);
	t.IsCollision(0.1);
	return 0;
}