// 처음 두 원이 접하지도 교차하지도 않은 상태를 가정함.
#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 ;
}
Ly8g7LKY7J2MIOuRkCDsm5DsnbQg7KCR7ZWY7KeA64+EIOq1kOywqO2VmOyngOuPhCDslYrsnYAg7IOB7YOc66W8IOqwgOygle2VqC4KCiNpbmNsdWRlIDxjbWF0aD4KI2luY2x1ZGUgPGNzdGRpbz4KI2luY2x1ZGUgPHN0YWNrPgoKI2RlZmluZSBQSSAzLjE0MTU5CgovLyB4LHkg7KKM7ZGcCmNsYXNzIFBPSU5UCnsKcHJvdGVjdGVkOgoJZmxvYXQgeDsKCWZsb2F0IHk7CgpwdWJsaWM6CglQT0lOVChmbG9hdCBfeCwgZmxvYXQgX3kpCgkJOngoX3gpLCB5KF95KQoJewoKCX0KfTsKCi8vIOybkApjbGFzcyBDSVJDTEUgOiBwdWJsaWMgUE9JTlQKewpwcml2YXRlOgoJZmxvYXQgcjsKCWZsb2F0IGQ7CglmbG9hdCBzZXRhOwoKcHVibGljOgoJQ0lSQ0xFKGZsb2F0IF94LCBmbG9hdCBfeSwgZmxvYXQgX3IsIGZsb2F0IF9kLCBmbG9hdCBfc2V0YSkKCQk6UE9JTlQoX3gsX3kpLCByKF9yKSwgZChfZCksIHNldGEoX3NldGEvUEkpCgl7CgkJcHV0cygi7IOd7ISxICYg7LSI6riw7ZmUIOyEseqztSAiKTsKCX0KCS8vIHNlY29uZCpk66GcIOybgOyngeyduCDsnbTtm4TsnZggeCx5Cgl2b2lkIE1vdmVQZXJTZWNvbmQoY29uc3QgZmxvYXQgc2Vjb25kKQoJewoJCWZsb2F0IG9sZF94ID0geDsKCQlmbG9hdCBvbGRfeSA9IHk7CgkJeCA9IHggKyBkICogc2Vjb25kICogY29zKHNldGEpOwoJCXkgPSB5ICsgZCAqIHNlY29uZCAqIHNpbihzZXRhKTsKCQlwcmludGYoIiglLjJmLCUuMmYpIC0+ICglLjJmLCUuMmYpXG4iLCBvbGRfeCwgb2xkX3ksIHgsIHkpOwoJfQoKCWZsb2F0IERpc3RhbmNlQmV0d2VlblR3b0NpcmNsZShjb25zdCBDSVJDTEUmIGMpCgl7CgkJcmV0dXJuIHNxcnQocG93KHRoaXMtPnggLSBjLngsIDIpICsgcG93KHRoaXMtPnkgLSBjLnksIDIpKTsKCX0KCgl2b2lkIENhbGN1bGF0ZUludGVyc2VjdFBvc2l0aW9uKGNvbnN0IENJUkNMRSYgYykKCXsKCgkJZmxvYXQgc3VtX3IgPSB0aGlzLT5yICsgYy5yOwoJCWZsb2F0IHBvaW50X3ggPSB0aGlzLT54Kih0aGlzLT5yIC8gc3VtX3IpICsgYy54KihjLnIgLyBzdW1fcik7CgkJZmxvYXQgcG9pbnRfeSA9IHRoaXMtPnkqKHRoaXMtPnIgLyBzdW1fcikgKyBjLnkqKGMuciAvIHN1bV9yKTsKCgkJcHJpbnRmKCLstqnrj4wg7KKM7ZGcIDogKCUuMmYsICUuMmYpIFxuIiwgcG9pbnRfeCwgcG9pbnRfeSk7Cgl9CgoJZmxvYXQgR2V0UmFkaXVzKCkKCXsKCQlyZXR1cm4gdGhpcy0+cjsKCX0KfTsKCmNsYXNzIFRlc3RDb2xsaXNpb24Kewpwcml2YXRlOgoJQ0lSQ0xFKiBjMTsKCUNJUkNMRSogYzI7CgpwdWJsaWM6CglUZXN0Q29sbGlzaW9uKGNvbnN0IENJUkNMRSYgX2MxLCBjb25zdCBDSVJDTEUmIF9jMikKCXsKCQljMSA9IG5ldyBDSVJDTEUoX2MxKTsKCQljMiA9IG5ldyBDSVJDTEUoX2MyKTsKCX0KCgl+VGVzdENvbGxpc2lvbigpCgl7CgkJZGVsZXRlIGMxOwoJCWRlbGV0ZSBjMjsKCX0KCgkvLyDrkZAg7JuQIOyCrOydtOydmCDqsbDrpqwKCWZsb2F0IERpc3RhbmNlQmV0d2VlblR3b0NpcmNsZSgpCgl7CgkJcmV0dXJuIGMxLT5EaXN0YW5jZUJldHdlZW5Ud29DaXJjbGUoKmMyKTsKCX0KCS8vIOuRkCDsm5DsnZgg7KCR7KCQ7J2YIOyijO2RnC4KCXZvaWQgQ2FsY3VsYXRlSW50ZXJzZWN0UG9zaXRpb24oKQoJewoJCWMxLT5DYWxjdWxhdGVJbnRlcnNlY3RQb3NpdGlvbigqYzIpOwoJfQoJLy8g65GQIOybkOydtCDstqnrj4ztlZjripTsp4Agc2Vjb25k66W8IOymneqwgOyLnO2CpOuptOyEnCDthYzsiqTtirgKCXZvaWQgSXNDb2xsaXNpb24oZmxvYXQgc2Vjb25kKQoJewoJCWZsb2F0IGMxX3JhZGl1cyA9IGMxLT5HZXRSYWRpdXMoKTsKCQlmbG9hdCBjMl9yYWRpdXMgPSBjMi0+R2V0UmFkaXVzKCk7CgoJCXN0ZDo6c3RhY2s8ZmxvYXQ+IHM7CgkJZmxvYXQgZGlzdGFuY2UgPSBEaXN0YW5jZUJldHdlZW5Ud29DaXJjbGUoKTsKCQlzLnB1c2goZGlzdGFuY2UpOwoKCQl3aGlsZSAodHJ1ZSkKCQl7CgkJCWMxLT5Nb3ZlUGVyU2Vjb25kKHNlY29uZCk7CgkJCWMyLT5Nb3ZlUGVyU2Vjb25kKHNlY29uZCk7CgkJCWRpc3RhbmNlID0gRGlzdGFuY2VCZXR3ZWVuVHdvQ2lyY2xlKCk7CgoJCQlpZiAoZGlzdGFuY2UgPD0gYzFfcmFkaXVzICsgYzJfcmFkaXVzKQoJCQl7CgkJCQlwdXRzKCLstqnrj4wg67Cc7IOdICIpOwoJCQkJQ2FsY3VsYXRlSW50ZXJzZWN0UG9zaXRpb24oKTsKCQkJCWJyZWFrOwoJCQl9CgkJCWVsc2UKCQkJewoJCQkJcHJpbnRmKCLstqnrj4wg7JWI7ZWoIOqxsOumrCAlZiBcbiIsZGlzdGFuY2UpOwoJCQkJc2Vjb25kICs9IDAuMTsKCQkJCQoJCQkJLy8g7Lap64+M7J20IOqzhOyGjSDslYjtlZjripQg6rK97Jqw7JeQ64qULCDrsKnquIgg7KCE7J2YIGRpc3RhbmNl6rCAIOyngOq4iOuztOuLpCDsp6fri6TrqbQg6re46rKMIOqwgOyepSDqsIDquYzsmrQg6rKDLgoJCQkJaWYgKHMudG9wKCkgPCBkaXN0YW5jZSkKCQkJCXsKCQkJCQlwcmludGYoIiVm6rCAIOqwgOyepSDqsIDquYzsmrQg6rGw66asXG4iLCBzLnRvcCgpKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJCWVsc2UKCQkJCXsKCQkJCQlzLnB1c2goZGlzdGFuY2UpOwoJCQkJfQoJCQl9CgkJfQoJfQp9OwoKaW50IG1haW4oKQp7CglDSVJDTEUgYzEoMTAuMGYsIDEwLjBmLCA1LjBmLCA2LjBmLCA2MC4wZik7CglDSVJDTEUgYzIoMjAuMGYsIDIwLjBmLCA1LjBmLCA1LjBmLCA2MC4wZik7CgoJVGVzdENvbGxpc2lvbiB0KGMxLCBjMik7Cgl0LklzQ29sbGlzaW9uKDAuMSk7CglyZXR1cm4gMDsKfQ==
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)