로그인

검색

MoA
조회 수 1772 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 게시글 수정 내역 댓글로 가기 인쇄 첨부
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 게시글 수정 내역 댓글로 가기 인쇄 첨부

먼저 간단한 삼각함수부터 생각하자. 아래 삼각형에서 각 A는 어떻게 구할까?

 

triangle.png

 

답은 간단하다 atan ( BC / AB ) 값을 구하면 된다. 그러므로 플레이어를 C로 바라보게 하려면 atan (BC / AB) 값 만큼 회전 시키면 된다. 선분 AB를 기준으로 하였을 때 점 C의 반대편으로 바라보게 하려면 atan (BC / AB) 의 마이너스 값만큼 회전 시키면 된다. 만약 A 위치를 원점으로 놓고 B는 (x, 0), C는 (x, y)로 놓는 다면 점 C'의 위치는 (x, -y)가 된다. atan ( y/x ) = - atan ( -y/x ) 이므로 플레이어를 회전할 각은 atan ( y/x )로 계산하면 될 것 같다.

 

하지만 다음 그림에서 점 C 방향으로 보게하려면 어떻게 계산해야할까?

 

triangle2.png

 

점 C의 좌표는 (-x, y)이다. 위에서처럼 atan ( y / (-x) )로 계산하면 atan ( -y / x ) 와 같은 값을 같게 된다. 예를 들어 x = 1, y = 1라면 두 경우 모두 atan ( -1 ) = -45도가 되어 버린다.

 

이를 위해 프로그래밍 언어에서는 보통 atan2 ( y, x ) 함수를 제공한다. 이는 x, y 각각의 부호를 판별하여 각도를 계산하게 해준다. 즉 atan2 ( -1, 1 )을 계산하면 -45도, atan2 ( 1, -1 )을 계산하면 135도가 된다.

 

이를 이용하여 플레이어를 회전시켜 보자. screen.blit(player, playerpos) 부분을 아래와 같이 바꾼다.

 

# 6.1 - 플레이어를 회전시킨다.
    mousepos= pygame.mouse.get_pos()
    angle = math.atan2(-mousepos[1]+(playerpos[1]),mousepos[0]-(playerpos[0]))
    rotPlayer = pygame.transform.rotate(player, angle*57.29)
    screen.blit(rotPlayer, playerpos)

mousepos에는 mouse.get_pos() 함수로 마우스의 좌표가 얻어진다. 두 번째 줄은 atan2( y, x )를 계산하는데 플레이어 좌표를 기준으로 계산해야 하므로 atan2 ( mouse y좌표 - player y좌표 , mouse x좌표 - player x 좌표 ) 를 계산한 것이다. 그런데 화면의 좌표는 아래 방향으로 y값이 증가하므로 (mouse y좌표 - player y좌표) 부호가 반대로 바뀌어야 한다.

 

이렇게 하여 계산된 angle값은 라디안 값이므로 degree (도)로 바꾸려면 angle * 180.0 / 3.14 = angle * 57.29를 계산하면 된다. 세 번째 줄은 이 값을 계산하여 player를 회전시킨 것이다. 그리고 회전된 player 이미지는 rotPlayer 이미지로 바뀌고 이를 playerpos 위치에 그렸다.

 

여기서 한가지 더 문제가 있다. 플레이어를 회전시키면 아래와 같이 이미지 크기가 변한다.

 

rotPlayer.png

 

회전 시켰더니 이미지 크기가 커졌다. 그리고 이미지는 왼쪽 위 좌표를 기준으로 그려지는데 이 또한 바뀌었다. 그런데 왼쪽 위 좌표를 항상 (100, 100) 위치시키면 player 위치가 이상하게 변한다. (직접 실행해서 확인해보라) 플레이어를 자연스럽게 회전시키려면 이미지의 중심 좌표를 기준으로 회전시켜야 한다. 이를 반대로 하여 회전시킨 후 중심 좌표를 똑같게 만들어도 된다. 이미지의 중심 좌표는 왼쪽 위 꼭지점에서 (이미지 가로크기/2 , 이미지 세로크기/2 ) 만큼 이동한 위치이므로 이 중심좌표를 왼쪽위 꼭지점으로 옮기게 하려면 다음과 같이 하면 된다.

 

    # 6.1 - 플레이어를 회전시킨다.
    mousepos = pygame.mouse.get_pos()
    angle = math.atan2(-mousepos[1]+(playerpos[1]),mousepos[0]-(playerpos[0]))
    rotPlayer = pygame.transform.rotate(player, angle*57.29)
    playerRotPos = (playerpos[0]-rotPlayer.get_rect().width/2, playerpos[1]-rotPlayer.get_rect().height/2)
    screen.blit(rotPlayer, playerRotPos)

직접 실행해보고 결과를 확인해 보길 바란다.

 

덧1 : 나의 경우엔 y좌표 부호를 반대로 하여 계산하였는데 취향에 따라 y 부호는 그대로 하고 rotation 시킬 때 반대로 회전시킬 수도 있다. 하지만 수학 공부 좀 한 사람에게는 계산이 많아지면 더 헷갈릴 수도 있다.

덧2 : 13살짜리가 탄젠트 역함수, 라디안도 암 ㄷㄷㄷ

 

 

?

List of Articles
번호 분류 제목 글쓴이 날짜 조회 수
공지 Tool/etc Programming 게시판 관련 2 MoA 2014.11.01 5303
288 API/MFC 후킹 링크 MoA 2013.07.28 1498
287 Python 화면 캡쳐 소스 MoA 2014.01.14 1379
286 API/MFC 프린터 출력하기 MoA 2013.10.16 4404
285 API/MFC 프로세스 - 생성과 종료 그리고 이것 저것 너울 2011.10.12 2175
284 API/MFC 프로그램 배포용으로 만드는 과정 너울 2012.01.20 1608
283 Site 프로그래밍 관련 사이트 MoA 2012.08.02 641
282 C/C++ 파일 입출력 MoA 2013.07.28 1177
281 Python 파이썬에서 C모듈 사용하기 MoA 2014.02.10 2543
280 Deeplearning 파이썬 머신러닝 무료 강의 (7시간) OBG 2022.07.06 460
279 Site 특정 자료형의 데이터를 binary(hex값, 2진수값)으로 변환 Naya 2012.11.15 1111
278 Tool/etc 텍스트 에디터 Sublime Text 2 너울 2012.03.30 1134
277 API/MFC 태스크 대화상자 (Task Dialog) MoA 2013.10.22 998
276 Algorithm 큰 수 구하기 알고리즘 Naya 2012.08.02 1317
275 Tool/etc 쿠버네티스 클러스터 OBG 2022.11.11 1110
274 C/C++ 코드 실행 시간 계산 Naya 2012.08.02 741
273 C/C++ 코드 실행 시간 계산 Naya 2012.09.27 1259
272 Tool/etc 컨텍스트 스위칭 (Context Switching) MoA 2013.07.28 1796
271 Web 카카오톡 웹버전 만들기 OBG 2022.11.09 752
270 Deeplearning 추천(Recommendation) 시스템 - 알고리즘 Trend 정리 OBG 2021.08.03 734
269 Deeplearning 추천 시스템 OBG 2023.03.30 933
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 ... 15 Next
/ 15