C++ 2D

8. 원과 사각형

seqw 2021. 6. 8. 03:59
원과 원의 충돌체크를 하는데는 피타고라스의 정리가 들어간다함.
미쳐버리겠네 진짜.

RECT rc1,rc2;

float x,y

원과 원의 충돌 공식

if(반지름 >= H) <- 충돌 식

 

A(rc1)와 B(rc2)의 반지름은 아래와 같다.

rc1의 반지름 = (rc1.right - rc1.left)/2

rc2의 반지름 = (rc2.right - rc2.left)/2


(rc1.right - rc1.left)/2
(오른쪽 좌표 - 왼쪽 좌표)/2

만약 오른쪽이 200 왼쪽이 100이라면

(200-100)/2
100/2	<-지름
50	<-반지름


ps1. 햇갈리는 것

(rc1.right + rc1.left)/2

비슷한 식이지만 이건 rc1의 중점좌표를 구하는 식이다.

(rc1.right - rc1.left)/2 + rc1.left

이것과 같다.

 

H 는 빗변.

H = sqrtf(powf(x,2)+powf(y,2))

공식은 위와 같다

위의 함수의 경우
sqrtf()는 제곱근의 역할을 하는 함수이다.
powf()는 제곱의 역할을 하는 함수이다.

powf()의 경우 powf(x,2); 의 경우 x의 2제곱이 된다.

x와 y는 rc1과 rc2의 중점좌표인데 계산은 아래와 같다.

x = ((rc1.left + rc1.right) / 2) - ((rc2.left + rc2.right) / 2)
x = rc1의 x축 중점좌표 - rc2의 x축 중점좌표

y = ((rc1.top + rc1.bottom) / 2) - ((rc2.top + rc2.bottom) / 2)
y = rc1의 y축 중점좌표 - rc2의 y축 중점좌표

 

이제 제일 끔찍한 부분이다

 

원과 사각형의 충돌

 

//평범한 1.번 해결법.
	1. //꼭짓점 계산
	if (ra(_rc1) >= hypo2(_rc1, _rc2.left, _rc2.bottom)
		|| ra(_rc1) >= hypo2(_rc1, _rc2.left, _rc2.top) 
		|| ra(_rc1) >= hypo2(_rc1, _rc2.right, _rc2.top)
		|| ra(_rc1) >= hypo2(_rc1, _rc2.right, _rc2.bottom))
	{
		_red = true;
	}
    2. // 좌우
	else if (_rc1.bottom >= _rc2.top	
		&&_rc1.top <= _rc2.bottom		
		&&_rc2.left < WINSIZEX / 2		
		&& _rc2.right > WINSIZEX / 2)	
	{
		_red = true;
	}
    3. //위아래
	else if(_rc1.left <= _rc2.right		
		&&_rc1.right>=_rc2.left			
		&&_rc2.top < WINSIZEY / 2		
		&& _rc2.bottom > WINSIZEY / 2)	
	{
		_red = true;
	}
	else // 아닐경우
	{
		_red = false;
	}

1.

1. 꼭지점 계산.

(ra(_rc1) >= hypo2(_rc1, _rc2.left, _rc2.bottom)

ra() 	<- 임의로 만든 반지름 계산 함수. ra(_rc1)의 경우 _rc1의 반지름을 구함.
hypo2() <-임의로 만든 H값 계산 함수.

반지름 + 반지름의 경우 하나는 원이고 하나는 점이기 때문에 반지름이 없어서 반지름을 1개만 사용
H가 반지름보다 작거나 같을때 충돌



2. 좌우 계산

_rc1의 밑이 _rc2의 위보다 크거나 같고 
_rc1의 위가 _rc2의 아래보다 작거나 같고
_rc2의 좌가 _rc2의 중점보다 작고
_rc2의 밑이 _rc1의 중점보다 작은 경우. true값이 된다.

쉽게 말해서
_rc1의 좌우가 _rc2의 좌우와 겹쳐있고
_rc1의 중점이 _rc2의 위아래 사이에 있을 때 참이 된다.

3. 위아래 계산

_rc1의 좌가 _rc2의 우보다 작거나 같고
_rc1의 우가 _rc2의 좌보다 크거나 같고
_rc2의 위가 _rc1의 중점보다 크고
_rc2의 밑이 _rc1의 중점보다 작을 경우. true값이 된다.

이 또한 쉽게 말하면
 _rc1의 좌우가 _rc2의 좌우와 겹쳐있고
_rc1의 줌점이 _rc2의 위아래 사이에 있을 때 참이 된다.



//진짜 기발하고 개쩔어버리는 2.번 해결법.
	if (IntersectRect(&_rcT,&_rc1,&_rc2)&& hypo2(_rc2,_rc2.left,_rc2.top) + ra(_rc2) >= hypo1(_rc1, _rc2)) _red = true;
	else _red = false;
    
    짧고 강렬하다.

사각형인 _rc2에 그림과 같이 사각형 밖에 원을 씌운다.

이 경우 반지름의 계산식이

_rc1의 반지름 + _rc2의 반지름 이 아닌.

_rc1의 반지름 + (_rc2의 중점과 _rc2의 left,top 사이의 H값) 이 된다.

 

이렇게 하면 마법같이 _rc2의 큰 원과 _rc1의 원이 충돌을 먼저 하고

 

이때 IntersectRect로 인해 원이 사각형과 닿지 않으면 if문이 참이 되지 않고 그로 인해서 사각형과 원이 아주 이쁘게 충돌이 된다.

 

진짜 기가막힌 생각이라 생각한다.

씽크빅이 분명하다.