갈고리 모양(구멍이 뚫려있는 고리 모양) 오브젝트의 충돌체크를 하는 방법에 대한 글이에요


그리고 저도 잘 아는게 아니고 제가 이해한 범위 안에서 쓰는거라 틀리거나 잘못된 내용이 있을수도 있어요



ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ




1. 갈고리와 점의 충돌체크




3fec9e36ebd518986abce89547837c6f50




위의 그림처럼 중심점의 좌표가 x1,y1 이고 중심의 각도가 a1, 중심부터 가장자리까지 각도의 범위가 s1,


안쪽 반지름의 길이가 ir1이고 바깥쪽 반지름의 길이가 or1인 갈고리 모양의 도형이 있을때


점 x2,y2가 저 갈고리 모양 영역의 내부에 포함되려면, 두가지 조건을 만족해야 해요




첫번째로 x1,y1에서 x2,y2까지의 각도가(arctan2로 구할수 있어요) a1+s1 과 a1-s1사이의 범위 안에 들어와야 해요


즉, 첫번째로 구한 두 점을 이어주는 각도와 a1 사이의 각도가 s1보다 작아야 해요




그리고 두번째로 두 점 사이의 거리 d가


ir1보다 크고 or1보다 작아야 해요




그리고 위의 두 조건을 만족하면, 해당 점은 갈고리 모양의 범위 안에 포함되게 되는거에요



https://gall.dcinside.com/m/game_dev/162026


그리고 이때 두 각도 사이의 각도를 구하는 방법은 위에 올려놓은 글의 19번에서 설명하고 있는 방법이에요




ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

def hook_point(x1,y1,a1,s1,or1,ir1,x2,y2)

angle = Math.atan2(y2-y1,x2-x1)

if Math.acos(Math.cos(a1)*Math.cos(angle)+Math.sin(a1)*Math.sin(angle)) > s1

return 0

end

dist = ((x2-x1)**2+(y2-y1)**2)**0.5

if dist > or1 || dist < ir1

return 0

end

return 1

end

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ


위에 올려놓은 코드가 앞에서 설명한 방식으로 갈고리 모양과 점의 충돌체크를 하는 함수의 코드에요, ruby프로그래밍 언어로 작성한거에요


(x1,y1,a1,s1,or1,ir1,x2,y2)에 위에 나와있는 그림대로 값을 입력하면 충돌했다면 1을 그렇지 않다면 0을 출력해줘요





2. 갈고리와 원의 충돌체크





3fef9e36ebd518986abce89547857d69bf



앞과 동일한 조건에 점이 아닌 중심점의 좌표가 x2,y2고 반지름이 r2인 원이 주어졌을 경우에


이 원이 갈고리와 충돌하는지를 체크하려면 두가지 경우를 체크해야해요


우선 위의 그림은 첫번째 경우에요, 갈고리의 중심점에서 원의 중심점까지의 각도가 갈고리의 범위각 안에 포함되는 경우에요




그리고 이때는 두 중심점 사이의 거리 d가 or1+r2보다 작고 동시에 d+r2가 ir1보다 크면


원이 갈고리와 충돌하고 있다고 판정해요



3fee9e36ebd518986abce895478275686e




위의 그림은 두번째 경우에요, 갈고리의 중심점에서 원의 중심점 까지의 각도가 갈고리의 범위각 안에 포함되지 않는 경우에요


그리고 이때는 원이 위의 그림에서 주황색으로 표시된 갈고리의 양 끝 선분과 충돌한다면, 원이 갈고리와 충돌했다고 판정해요




https://gall.dcinside.com/m/game_dev/171644


그리고 이때 원이 선분과 충돌하는지 체크하는 방법은 위에 올려놓은 글의 2번에서 설명하고 있는 방법이에요




ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

def hook_circle(x1,y1,a1,s1,or1,ir1,x2,y2,r2)

angle = Math.atan2(y2-y1,x2-x1)

if Math.acos(Math.cos(a1)*Math.cos(angle)+Math.sin(a1)*Math.sin(angle)) > s1

vx1, vy1, vx2, vy2 = x1+ir1*Math.cos(a1+s1), y1+ir1*Math.sin(a1+s1), x1+or1*Math.cos(a1+s1), y1+or1*Math.sin(a1+s1)

vx3, vy3, vx4, vy4 = x1+ir1*Math.cos(a1-s1), y1+ir1*Math.sin(a1-s1), x1+or1*Math.cos(a1-s1), y1+or1*Math.sin(a1-s1)

if circle_line(vx1,vy1,vx2,vy2,x2,y2,r2) == 1 || circle_line(vx3,vy3,vx4,vy4,x2,y2,r2) == 1

return 1

end

return 0

end

dist = ((x2-x1)**2+(y2-y1)**2)**0.5

if dist > or1+r2 || dist+r2 < ir1

return 0

end

return 1

end

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ




그리고 위에 올려놓은 코드가 해당 방식으로 갈고리와 원의 충돌을 체크하는 함수의 코드에요


역시 (x1,y1,a1,s1,or1,ir1,x2,y2,r2)에 앞의 그림대로 값을 입력하면 충돌했다면 1을 그렇지 않으면 0을 출력해요


그리고 위의 함수를 사용하기 위해서는 앞에 올려놓은 글의 2번에 나와있는 원과 선분의 충돌을 체크하는 함수도 정의해 놓아야해요






그리고 위에 올려놓은 영상이 앞에서 설명한 방식으로 인게임에서 갈고리와 원의 충돌체크를 하는 영상이에요


파랑색 원이 플레이어가 방향키로 움직이는 오브젝트에요, 만약 중앙에서 회전하고 있는 연두색의 갈고리 모양 오브젝트와 충돌했다면 둘다 반투명하게 표시되요





그리고 이렇게 하면 갈고리 모양 오브젝트의 충돌체크를 할 수 있어요