1. 사각형 충돌
사각형의 도형간의 출력처리에 관한 함수입니다.
먼저 사각형이 서로 부딫혔을때에 대한 처리를 진행해야 하는데 따로 함수가 있기는 하지만 함수를 사용하지
않고 처리하게 되면 조건이 너무 번거롭게 됩니다.
아마 아래와 같은 형식의 조건문이 필요할 것 입니다.
if ( RC_Left.left < RC_Right &&
RC_Left.Top < RC2_Right.bottom &&
RC_Left.right > RC_Right.left &&
RC_Left.bottom > RC_Right.top)
모든 사각형끼리의 각 위치의 값을 더해야 하지만 다음 함수를 통해 쉽게 해결 할 수 있습니다.
IntersectRect
해당 함수는 두가지의 사각형의 교차점을 계산하고 서로 교차하는 지점이 있는지를 확인해주는 함수입니다.
IntersectRect 함수로는 교차지점의 넓이를 알 수는 없으며, 교차하는지의 여부만 bool 값으로 반환됩니다.
BOOL IntersectRect( _Out_ LPRECT lprcDst, _In_ const RECT *lprcSrc1, _In_ const RECT *lprcSrc2 ); |
매게 변수 | 의미 |
lprcDst | RECT 구조체를 포인터 값입니다. 해당 구조체에 lprcSrc1 , lprcSrc2에서 지정된 사각형들의 교차점을 받을 수 있습니다. 해당 매개 변수는 NULL 일 수 없습니다. |
*lprcSrc1 | 비교할 첫번째 RECT 구조체를 포인터 값입니다 |
*lprcSrc2 | 비교할 두번째 RECT 구조체를 포인터 값입니다 |
대부분 첫번째 매개 변수에는 임시 매개변수를 삽입하여 사용합니다.
예) bool collisonBox = IntersectRect ( &rcTemp , &RC_Left , &RC_right) |
2. 원형 충돌
위 IntersectRect 함수를 통해서 원형 충돌을 하려고 하면 아래와 같이 떨어져 있는데도 불구하고
IntersectRect 값이 true로 오게됩니다.
IntersectRect 로 충돌처리를 하는 좌표에 이미 사각형에 대한 좌표로 충돌처리를 구분하기 때문인데,
윈도우 API에서는 원형충돌 함수를 따로 지원해주지 않습니다.
두 원의 충돌은 두 원의 중심 사이의 거리만을 판단하여 계산하며, 이 거리가 두원의 반지름의 길이의 합도다 크면 충돌이 아니고 작으면
충돌처리라는 기능을 구현하면 된다고 합니다.
즉 dist.x * dist.x + dist.y * dist.y 값의 의 제곱근에 각 원의 반지름을 합한 값을 비교하면 됩니다.
또한 여기서는 sqrt 함수 (제곱근을 구하는 함수)가 필요합니다.
만약 제곱근을 사용하지 않을 것이라면 dist.x * dist.x + dist.y * dist.y <= (radius1 + radius2) * (radius1 + radius2) 으로
우변에 값을 한 번씩 더하고 곱해주면 됩니다.
좌측의 서로 중점간의 거리는 r1,r2 합보다 작습니다. (충돌 O)
우측의 서로 중점간의 거리는 r1,r2 합보다 큽니다. (충돌 X )
우리가 구하고자하는 각 원의 중점간의 거리인(AB)의 거리는 피타고라스의 정리을 이용하면 AC^2 + BC^2 = AB^2 이기 때문에 각 식의
제곱을 곱해준 값으로 구해주는 것 입니다.
[요약]
BC = r1의 중점에서 r2중점을 뺸 X 값 (길이)
AC = r1의 중점에서 r2중점을 뺸 Y 값 (길이)
다음은 해당 충돌을 구하는 함수를 구현한 것입니다.
bool collisionEllipseCheck( RECT rc , RECT rc2 )
{
float rc_R = (rc.right - rc.left ) / 2 ;
float rc2_R = ( rc2.right - rc2.left ) / 2;
float rX = ( rc.left + (rc.right - rc.left) / 2 ) - ( rc2.left + (rc2.right - rc2.left) / 2 );
float rY =( rc.top + (rc.bottom - rc.top) / 2 )- ( rc2.top + (rc2.bottom - rc2.top) / 2 );
float length = ( rc_R + rc2_R) * (rc_R + rc2_R );
if ( length >= (rX * rX + rY * rY ) )
{
return true;
}
return false;
}
//결과 |
이전것은 뭔가 잘못되었더군요..알아보기도 어렵고..그래서 RECT를 인자값으로 받아서 계산하는 식으로
다시 함수를 만들었습니다. (진작에 이럴것을...) 이제 2개의 원을 그린후에 서로간이 충돌하는지를 보면 됩니다.
결과로는 마우스 좌표를 따라다니는 원이 화면안에 다른 원과 충돌하면 다른원이 빨간색으로 표시됩니다.
'프로그래밍 관련 > Win API' 카테고리의 다른 글
WIndows API - #9 -2. 그래픽 처리 (Old를 같이 쓰는 이유) (2) (0) | 2015.09.03 |
---|---|
WIndows API - #9 -1. 그래픽 처리 (Old를 같이 쓰는 이유) (1) (0) | 2015.09.03 |
WIndows API - #7. 키보드, 마우스 입력, 좌표 (InvalidateRect) (0) | 2015.09.01 |
WIndows API - #6. API 문자열 출력 함수들에 관하여.. (0) | 2015.08.24 |
WIndows API - #5. 윈도우 문자열 (0) | 2015.08.24 |