fork download
  1. // 처음 두 원이 접하지도 교차하지도 않은 상태를 가정함.
  2.  
  3. #include <cmath>
  4. #include <cstdio>
  5. #include <stack>
  6.  
  7. #define PI 3.14159
  8.  
  9. // x,y 좌표
  10. class POINT
  11. {
  12. protected:
  13. float x;
  14. float y;
  15.  
  16. public:
  17. POINT(float _x, float _y)
  18. :x(_x), y(_y)
  19. {
  20.  
  21. }
  22. };
  23.  
  24. // 원
  25. class CIRCLE : public POINT
  26. {
  27. private:
  28. float r;
  29. float d;
  30. float seta;
  31.  
  32. public:
  33. CIRCLE(float _x, float _y, float _r, float _d, float _seta)
  34. :POINT(_x,_y), r(_r), d(_d), seta(_seta/PI)
  35. {
  36. puts("생성 & 초기화 성공 ");
  37. }
  38. // second*d로 움직인 이후의 x,y
  39. void MovePerSecond(const float second)
  40. {
  41. float old_x = x;
  42. float old_y = y;
  43. x = x + d * second * cos(seta);
  44. y = y + d * second * sin(seta);
  45. printf("(%.2f,%.2f) -> (%.2f,%.2f)\n", old_x, old_y, x, y);
  46. }
  47.  
  48. float DistanceBetweenTwoCircle(const CIRCLE& c)
  49. {
  50. return sqrt(pow(this->x - c.x, 2) + pow(this->y - c.y, 2));
  51. }
  52.  
  53. void CalculateIntersectPosition(const CIRCLE& c)
  54. {
  55.  
  56. float sum_r = this->r + c.r;
  57. float point_x = this->x*(this->r / sum_r) + c.x*(c.r / sum_r);
  58. float point_y = this->y*(this->r / sum_r) + c.y*(c.r / sum_r);
  59.  
  60. printf("충돌 좌표 : (%.2f, %.2f) \n", point_x, point_y);
  61. }
  62.  
  63. float GetRadius()
  64. {
  65. return this->r;
  66. }
  67. };
  68.  
  69. class TestCollision
  70. {
  71. private:
  72. CIRCLE* c1;
  73. CIRCLE* c2;
  74.  
  75. public:
  76. TestCollision(const CIRCLE& _c1, const CIRCLE& _c2)
  77. {
  78. c1 = new CIRCLE(_c1);
  79. c2 = new CIRCLE(_c2);
  80. }
  81.  
  82. ~TestCollision()
  83. {
  84. delete c1;
  85. delete c2;
  86. }
  87.  
  88. // 두 원 사이의 거리
  89. float DistanceBetweenTwoCircle()
  90. {
  91. return c1->DistanceBetweenTwoCircle(*c2);
  92. }
  93. // 두 원의 접점의 좌표.
  94. void CalculateIntersectPosition()
  95. {
  96. c1->CalculateIntersectPosition(*c2);
  97. }
  98. // 두 원이 충돌하는지 second를 증가시키면서 테스트
  99. void IsCollision(float second)
  100. {
  101. float c1_radius = c1->GetRadius();
  102. float c2_radius = c2->GetRadius();
  103.  
  104. std::stack<float> s;
  105. float distance = DistanceBetweenTwoCircle();
  106. s.push(distance);
  107.  
  108. while (true)
  109. {
  110. c1->MovePerSecond(second);
  111. c2->MovePerSecond(second);
  112. distance = DistanceBetweenTwoCircle();
  113.  
  114. if (distance <= c1_radius + c2_radius)
  115. {
  116. puts("충돌 발생 ");
  117. CalculateIntersectPosition();
  118. break;
  119. }
  120. else
  121. {
  122. printf("충돌 안함 거리 %f \n",distance);
  123. second += 0.1;
  124.  
  125. // 충돌이 계속 안하는 경우에는, 방금 전의 distance가 지금보다 짧다면 그게 가장 가까운 것.
  126. if (s.top() < distance)
  127. {
  128. printf("%f가 가장 가까운 거리\n", s.top());
  129. break;
  130. }
  131. else
  132. {
  133. s.push(distance);
  134. }
  135. }
  136. }
  137. }
  138. };
  139.  
  140. int main()
  141. {
  142. CIRCLE c1(10.0f, 10.0f, 5.0f, 6.0f, 60.0f);
  143. CIRCLE c2(20.0f, 20.0f, 5.0f, 5.0f, 60.0f);
  144.  
  145. TestCollision t(c1, c2);
  146. t.IsCollision(0.1);
  147. return 0;
  148. }
Success #stdin #stdout 0s 3464KB
stdin
Standard input is empty
stdout
생성 & 초기화 성공 
생성 & 초기화 성공 
(10.00,10.00) -> (10.58,10.15)
(20.00,20.00) -> (20.48,20.12)
충돌 안함 거리 14.056271 
(10.58,10.15) -> (11.74,10.44)
(20.48,20.12) -> (21.45,20.37)
충돌 안함 거리 13.885107 
(11.74,10.44) -> (13.49,10.89)
(21.45,20.37) -> (22.91,20.74)
충돌 안함 거리 13.629834 
(13.49,10.89) -> (15.81,11.48)
(22.91,20.74) -> (24.85,21.23)
충돌 안함 거리 13.292377 
(15.81,11.48) -> (18.72,12.22)
(24.85,21.23) -> (27.27,21.85)
충돌 안함 거리 12.875596 
(18.72,12.22) -> (22.21,13.11)
(27.27,21.85) -> (30.18,22.59)
충돌 안함 거리 12.383593 
(22.21,13.11) -> (26.28,14.14)
(30.18,22.59) -> (33.57,23.45)
충돌 안함 거리 11.822203 
(26.28,14.14) -> (30.93,15.32)
(33.57,23.45) -> (37.44,24.44)
충돌 안함 거리 11.199746 
(30.93,15.32) -> (36.17,16.66)
(37.44,24.44) -> (41.81,25.55)
충돌 안함 거리 10.528194 
(36.17,16.66) -> (41.98,18.13)
(41.81,25.55) -> (46.65,26.78)
충돌 발생 
충돌 좌표 : (44.32, 22.46)