버섯돌이의 Python 거북이 그래픽(Turtle graphics) |
들어가며..
안녕하세요 버섯돌이 유재성입니다.
아무래도 애들은 딱딱한 것보다는 우와~ 우와~ 이런 감탄사를 자아내게 하거나 뭔가 신나는 것을 좋아하기 때문에
파이썬 사이트에서 프레임워크 중 그래픽 쪽을 찾아보니 turtle라는 프레임웍이 있네요.
저도 30년 전 초등학생 때 처음 컴퓨터를 접하면서 특수 명령어를 사용하면 점과 선의 그래픽이 가능하다는 사실을 알고는
신기해서 교보문고 컴퓨터 서적 코너에서 몇 달간 다양한 그래픽 소스 코드를 보는 족족 노트에 열심히 그렸던 기억이..^^;;
ㅎㅎㅎ.. 당시에 영어를 몰라서 최대한 똑같이 그린다고 그렸지만 언어가 달라서 안되는 명령어들이 많은....ㅠㅠ
분명, 아들도 이런류의 코딩은 재미있어 하리라 믿어 의심치 않으며 이번 시간에는 turtle을 살펴보겠습니다.
보다 자세한 내용은 아래의 파이썬 문서를 참고하시기 바랍니다.
https://docs.python.org/3.5/library/turtle.html
Turtle graphics란?
여기서 화살표로 가리키고 있는 삼각형 표시가 바로 거북이입니다.^^
에이~ 선생님 저게 무슨 거북이예요~~~~ 퍽퍽퍽!! 하실 수 있겠으나.. 뒤에서 설명드리겠습니다..쿨럭..
저 거북이는 그림판에 그림을 그리기 위한 붓이라고 보셔도 좋고 커서라고 보셔도 좋습니다.
정확한 용어를 찾아보기 귀찮으니 저는 그냥 거북이라고 부르겠습니다. (뭐.. 용어가 중요하겠습니까..^^)
아이들 학습용이라서 저 거북이가 도화지 위를 자유롭게 기어 다니면서 멋진 그림을 그리는 형태라고 보셔도 좋겠네요.
단순한 기능일 수 있으나 다양한 공식을 이용하면 위 그림처럼 간단한 명령만으로도 화려한 모양도 만들 수 있고..
지원되는 기능이 많아서 아이들의 수학이나 물리 공부에도 많은 도움을 줄 수 있습니다.
그러니 저 거북이를 어떻게 활용할지에 따라서 할 수 있는 작업은 무궁무진하겠지요?
turtle 모듈..
거북이 모듈을 사용하기 위해서는 아래와 같이 import 문을 이용해서 선언하면 됩니다.
import turtle
에러 없이 모듈이 import되면 turtle.forward(15) 처럼 사용할 수 있습니다.
이 명령을 실행하면 거북이 아이콘이 15픽셀만큼 전진합니다.
픽셀은 단순히 점 하나를 의미하며 15픽셀이면 15칸을 이동합니다.
참고로, 거북이가 움직이면 움직인 거리에는 선이 그려집니다.*^^*
별도의 코딩 없이도 파이썬의 장점(?)인 대화형 셀에서 곧바로 동작을 확인할 수 있습니다.
파이썬을 실행 후 아래처럼 명령을 하나씩 실행하면 됩니다.
turtle.forward(15) 명령이 실행되는 순간 위 그림처럼 "Python Turtle Graphics" 그래픽 창이 나오며
"Python Turtle Graphics" 그래픽 창을 보면 거북이(화살표)가 화살표 방향(거북이 머리)으로 15픽셀 정도 이동되어 있습니다.
참고로, "Python Turtle Graphics" 그래픽 창의 좌측 모서리가 아닌 정중앙 좌표가 (0,0)입니다.
turtle.forward(15)의 경우 OOP처럼 "거북아~ 앞으로 15픽셀만큼 가라~"라고 거북이 말을 해석하면 되겠습니다.^^;;;
아흑.. 보기 좋게 거북이 언어(?)를 예쁘장한 색상으로 번역해서 구분해봤습니다.
자꾸, 거북이~ 거북이~라고 말은 하지만 아무리 봐도 거북이 모양이 아니라 삼각형이죠? ^^
shape() 메서드를 이용해서 화살표 모양을 바꿀 수 있습니다.
참고로, turtle.shape의 사용법이 궁금하면 쉘에서 help(turtle.shape) 명령을 이용해서 확인할 수도 있습니다.
아래는 idle이 아닌 python으로 실행한 python의 대화형 셀에서 실행한 화면입니다. (idle도 동일합니다.)
지원되는 모양에는 arrow, circle, square, triangle, classic 외에도 거북이인 turtle가 있군요.
그럼, 아이들이 좋아하는 거북이로 모양을 변경합시다.*^^*V
turtle.shape("turtle")
와우~ 거북이로 변신했군요.*^^*
그림을 보면 거북이가 (0,0)의 중앙에서 15 픽셀만큼 오른쪽으로 이동했습니다.
자세히 보면 아이콘 특성상 거북이가 바라보는 방향을 기준으로 거북이가 앞이나 뒤로 이동하고...
거북이 꼬리에서 그림이 그려지는 느낌을 받을 수 있습니다.
네~~~ 꼬리 쪽에서 선이 그려지니.. 앞으로는 편하게 거북이 꼬리에 펜이 달려 있다고 생각하면 되겠습니다.*^^*
참고로, 대화형 셀은 위 그림처럼 한 번에 하나의 명령만 실행할 수 있습니다.
하지만, 세미콜론을 이용하면 한 줄에 여러 명령도 사용할 수 있습니다.
예를 들면, 위 그림의 경우 turtle.forward(15); turtle.shape("turtle");처럼 한 줄에 사용이 가능합니다.
세미콜론(;) 없이 ">>>" 위치에 줄 바꿈을 하더라도 여러 명령을 한 번에 사용하면 에러가 납니다.
또한, 매번 turtle.forward(15)처럼 turtle이라는 긴(?) 이름을 사용하는 게 번거롭다면...
"import turtle as tt"처럼 turtle 모듈에 별칭을 설정해서 간단히 사용할 수 있습니다.
펜 명령어..
기본 상태는 거북이가 꼬리를 내리고 있기 때문에 거북이가 움직일 때마다 그림(선)이 그려집니다.
만약, 거북이를 이동하면서 그림을 그리고 싶지 않다면 꼬리를 들어서 그림이 그려지지 않도록 해야겠지요^^
이때 그림을 그려야 할지 그리지 말아야 할지 결정하는 명령어가 pendown()과 penup()입니다.
- pendown() : 펜을 내리고 이동하기 때문에 선이 그려집니다.
pendown() 대신 pd()나 down()을 사용해도 동일합니다.
편하게 생각해서 꼬리에 펜이 달려있으니 꼬리를 내리면 그림이 그려지겠지요?
- penup() : 펜을 올리고 이동하기 때문에 선이 그려지지 않습니다.
penup() 대신 | pu()이나 up()을 사용해도 동일합니다.
역시나 꼬리에 펜이 달려있으니 꼬리를 올리고 이동하면 그림이 그려지지 않겠지요?
pendown()이 선을 그리는 것인지 선을 그리지 않는 것인지 헷갈릴 때에는 pen을 꼬리로 생각하면 되겠습니다.^^;;;
pensize()를 이용해서 거북이가 이동 시 그려지는 선의 굵기도 변경할 수 있습니다.
- pensize(선의 굵기) : 선의 굵기로서 기본 값은 1이며, 양수를 입력하면 됩니다.
(예) turtle.pensize(10)
거북이 이동 명령어..
이동 명령어 중 가장 기본이 되는 4가지를 살펴보면 다음과 같은 명령이 가능합니다.
아래 4가지의 메서드는 상대 좌표라서 현재 위치를 기준으로 동작합니다.
- forward(거리) : 지정된 거리(픽셀) 만큼 앞으로 갑니다.
forward() 대신 fd()를 사용해도 동일합니다.
- backward(거리) : 지정된 거리(픽셀) 만큼 뒤로 갑니다.
backward() 대신 bk()나 back()를 사용해도 동일합니다.
- right(각도) : 지정된 각도만큼 우측으로 방향을 바꿉니다.
right() 대신 rt()를 사용해도 동일합니다.
- left(각도) : 지정된 각도만큼 좌측으로 방향을 바꿉니다.
left() 대신 lt()를 사용해도 동일합니다.
goto() 대신 setpos()이나 setposition()를 사용해도 동일합니다.
위에서 "Python Turtle Graphics" 그래픽 창의 정중앙이 (0,0)이라고 했습니다.
(0,0)을 기준으로 x좌표 값이 양수이면 우측으로, 음수이면 좌측으로 이동합니다.
(0,0)을 기준으로 y좌표 값이 양수이면 위로, 음수이면 아래로 이동합니다.
거북이를 정중앙에서 오른쪽으로 100픽셀, 위로 100픽셀 위치로 이동시키고 싶다면 turtle.goto(100,100)으로 명령하면 됩니다.
주의할 점은, 당연하겠지만 현재 거북이의 위치에서 지정된 절대 좌표로 이동한 다는 것입니다.
따라서, turtle.forward(15)로 이동한 후 turtle.goto(100,100)로 이동하면 아래처럼 됩니다.
좌표 계산을 잘 하면 goto 메서드만으로도 멋진 그림을 그릴 수 있겠지요.^^
goto보다는 setposition이 좀 더 직관적(?)이라서 문서에서는 setposition을 더 많이 사용하는 듯싶네요.
x와 y좌표 모두를 입력하는 게 아닌 하나만 입력하면 되는 setx(x좌표), sety(y좌표) 메서드도 있습니다.
- setheading(각도) 메서드를 이용하면 거북이의 머리 방향을 변경할 수 있습니다.
각도는 기본 0도가 앞을 보고 있는 상태인데 지금까지의 사진을 보면 알 수 있듯이 우측을 바라보는 상태가 됩니다.
각도 값은 0부터 360까지 가능한데 절대 값으로서 앞을 보고있는 상태를 기준으로 거북이가 시계 반대 방향으로 회전합니다.
즉, 좌측으로 회전하며 각도를 90으로 설정하면 12시 방향을 가리킵니다.
위에서 설명했듯이 거북이의 방향은 left(), right() 함수를 이용해서도 변경할 수 있습니다.
setheading()은 좌측으로 회전하니까 left()와 비슷해 보일 수 있으나 left()의 경우 현재 위치에서 계속 회전하게 됩니다.
반면, setheading()은 절대 좌표라서 0도를 기준으로 해서 지정된 각도로 회전합니다.
즉, 3시 방향을 보고 있는 기본 상태에서 turtle.left(90)을 두 번 실행하면 거북이는 총 180도가 회전되어서 9시 방향을 바라보지만
turtle.setheading(90)은 아무리 많이 실행하더라도 12시 방향을 바라봅니다.
번거롭게 setheading()을 길게 설명한 이유는 home() 메서드 때문입니다.
- home() 메서드는 거북이를 최초 위치로 이동시키고 머리 방향을 0도로 초기화합니다.
즉, 거북이 머리가 12시 방향을 바라보고 있는 상태에서 turtle.goto(0,0)을 실행하면 거북이는 최초 위치로 이동합니다.
하지만 거북이 머리는 여전히 12시 방향을 바라보고 있습니다.
반면, turtle.home()을 실행하면 거북이는 최초 위치인 (0,0)으로 이동하면서 거북이 머리도 3시 방향으로 초기화됩니다.
- speed(속도) 메서드를 이용하면 거북이의 이동 속도를 조절할 수 있습니다.
속도는 1부터 10까지 지정이 가능하며 1이 제일 느리고 10이 가장 빠릅니다.
(예)
turtle.speed(1)
turtle.speed(10)
색상 명령어..
- color(펜 색상, 채움 색상) : 연필 색과 채움 색을 지정합니다.
색상은 "blue"처럼 영문 명으로 지정해도 되고 "#285078"처럼 16진수 값의 "#RGB" 형태로 지정할 수도 있습니다.
예를 들면,
turtle.color('red')처럼 펜 색상만 지정하거나 turtle.color('red','green')처럼 펜 색상과 채움 색상 모두 지정이 가능합니다.
color("#285078", "#a0c8f0") 형태로 RGB 값을 이용할 수도 있습니다.
참고로, 거북이의 경우 채움 색상은 의미가 없어서 첫 번째 항목의 연필 색으로 선이 그려지고 있습니다.
아래 begin_fill(), end_fill()의 예제처럼 속이 채워지는 도형을 그리면 채움 색상이 적용됩니다.
색상의 경우 pencolor()를 이용해서 펜의 색상만 지정할 수 있으며, fillcolor()를 이용해서 도형에 채워지는 색상만 지정할 수도 있습니다.
도형 명령어..
- dot() : 현재 위치에 점을 찍습니다.
dot(크기) 또는 dot('색상') 또는 dot(크기, '색상') 형태로 사용 가능합니다.
점의 크기(원의 지름)을 지정하지 않으면 pensize+4와 2*pensize의 최대 값이 사용됩니다.
위 그림은 거북이를 처음 위치에서 dot()으로 점을 한 번 찍고, 앞으로 50픽셀 이동한 후
turtle.dot(20, "blue")으로 색상과 크기를 지정해서 직경 20 픽셀 짜리 파란색 점을 찍습니다.
- circle(반지름 크기) : 현재 위치에 원을 그립니다.
circle(반지름 크기, 종료 각) 형태로도 사용이 가능하다. 종료 각의 경우 호(Arc)를 그릴 때 사용한다.
처음에는 circle(50) 명령으로 반지름 50짜리 원을 그렸으며, 보기 편하도록 150 픽셀만큼 이동 후
circle(50, 300) 명령으로 반지름 50짜리 원을 그리는데 이번에는 360도를 모두 그리는 게 아니라 300도까지만 그렸음.
기타 명령어..
- distance(x좌표, y좌표) : 현재 위치를 기준으로 특정 좌표와의 떨어진 거리를 조회합니다.
거북이 두 마리를 만들어서 거북이A가 거북이B와의 떨어진 거리를 확인할 수 도 있습니다.
>>> joe = Turtle() <-- joe라는 거북이를 새로 만듦
>>> joe.forward(77) <-- joe 거북이를 77만큼 전진 시킴.
>>> turtle.distance(joe) <-- 최초 만들어진 거북이 기준으로 joe와의 떨어진 거리를 확인 함.
77.0
- begin_fill(), end_fill() : begin_fill()과 end_fill() 사이에 도형을 그리면 내부가 채워진 도형이 그려진다.
원래는 반지름이 80인 원이 그려져야 하지만 begin_fill()과 end_fill() 사이에 있어서 빨간색으로 채워진 원이 만들어졌음.
- write() : 텍스트를 출력한다.
전체 입력 형식은 write(arg, move=False, align="left", font=("Arial", 8, "normal"))이며 생략이 가능하다.
대충 입력 값, 이동 여부, 정렬, 폰트 형태로 지정하는 것 같다.
turtle.write("Home = ", True, align="center")에 의해서 화면에 "Home="가 출력되었으며,
turtle.write((0,0), True)에 의해서 "(0,0)"이 출력되었음.
turtle.forward(100)은 좀 더 잘 보이라고 그냥 이동시킨 것임.
turtle.write("한글") 처럼 입력해도 됨.
- stamp() / clearstamp() / clearstamps() : 거북이 모양을 도장(스탬프) 찍듯이 현재 위치에 남기거나 특정 스탬프를 삭제합니다.
- undo() : 마지막으로 실행한 명령을 취소합니다.
- clear() : 거북이를 현재 위치에 남겨 놓은 상태로 화면의 그림을 모두 지웁니다.
- reset() : 화면의 그림을 모두 지운 후 거북이를 최초 상태(0,0)로 돌려놓습니다.
문서 예제..
이 강좌의 처음에 나왔던 그림인 파이썬 사이트의 예제를 실행하면 아래처럼 동작합니다.
소스 코드도 상당히 간단합니다.
from turtle import *
shape('turtle')
color ('red', 'yellow')
begin_fill()
while True:
forward(200)
left(170)
if abs(pos()) < 1:
break
end_fill()
done()
좀 더 귀엽게(?) 기본 모양을 거북이로 바꿔봤습니다.
2번째 라인에 shape('turtle') 만 추가하면 됩니다.^^
마치며..
아이들은 현재 명령어 만으로도 재미있게 놀 수 있으리라 보며 더 길어지면 피곤해서 이쯤에서 마무리합니다.
기초 기능으로 열심히 놀아 보기 바라며 다음에 시간이 되면 다시 다루도록 하겠습니다.
사용 가능한 명령어는 상당히 많이 있으며 자세한 설명은 문서를 참고하시기 바랍니다.
본 강좌가 조금이라도 도움이 되었길 바랍니다.
본문 수정 시 가급적 공유한 곳의 글 들도 함께 수정하려고 노력합니다만 누락되는 경우가 많습니다.^^;;;
[참고 자료]
이 저작물은 크리에이티브 커먼즈 저작자표시-비영리 3.0 Unported 라이선스에 따라 이용할 수 있습니다.
'기타 개발관련' 카테고리의 다른 글
[버섯] 버섯돌이의 Python - 프로그램 설치하기 (0) | 2016.09.08 |
---|---|
[버섯] SPA 개발을 위한 추천 프레임워크 AngularJS (0) | 2014.11.24 |
[펌] 큐 시스템을 이용한 NPUSH-GW 개선 (0) | 2014.11.23 |