파이썬 실전 프로젝트

거북이로 복잡한 그림 그리기(turtle 모듈)

토픽 파이썬 실전 프로젝트 > 파이썬 실전프로젝트

turtle 모듈로 한땀한땀 그림을 그릴수는 있습니다.

그런데 그렇게 그리다가는 사람하나 그리는데도 하루종일 걸릴것 같네요.

박스를 그려주는 함수를 만들기로 하겠습니다.

 

1. 거북이한테 크기와 색깔만 알려주면 자동으로 사각형 박스를 그려주는 함수를 만들기로 하죠.

텍스트 편집기를 열고, 함수를 작성하겠습니다.

import turtle as t

def box(x,y,color):
    t.color(color)
	t.fd(x)
	t.left(90)
	t.fd(y)
	t.left(90)
	t.fd(x)
	t.left(90)
	t.fd(y)

box(100,50,'red')
input("")

잘 작동하는지 확인하기 위해서, 함수를 호출하는 코드도 넣어주고,

Shell 창이 바로 안닫히도록 아래에 input 명령어도 하나 추가해주겠습니다.

2. 박스에 색깔도 채우고, 속도도 더 빠르게 바꾸도록 하겠습니다.

import turtle as t

def box(x,y,color):
    t.speed('normal') # 속도증가; slowest,slow,normal,fast,fastest
	t.color(color)
	t.begin_fill() # 색깔채우기, 시작부분 코드
	t.fd(x)
	t.left(90)
	t.fd(y)
	t.left(90)
	t.fd(x)
	t.left(90)
	t.fd(y)
	t.end_fill() # 색깔채우기, 종료부분 코드
	
box(100,50,'red')
input("")

t.speed(''normal') : 기본속도가 slow 인데 이걸, normal 로 바꿨습니다. 더 빠르게 할려면, fast나 fastest 로 하면 됩니다.

t.begin_fill()  / t.end_fill() : 박스의 시작점과 끝점에 각각 추가해주면, 둘이 만났을때 안쪽에 색깔을 채워줍니다.

3. 이제, 사람(?)을 그려보도록 하죠.

박스간의 이동시에, penup(), pendown(), goto() 함수를 적절히 써줘야 합니다.

다 그리지 말고, 일단 양 발만 먼저 그러보죠

#foot
t.penup()
t.goto(-100,-150)
t.pendown()
box(80,50,'blue')

t.penup()
t.goto(0,-150)
t.pendown()
box(80,50,'blue')

-100,-150 좌표로 이동해서, 왼발을 그리고, 0,-150 좌표로 이동해서 오른발을 그리도록 했습니다.

뭔가 잘못됐네요. 어디일까요??

원인은 박스 함수안에 있네요. left(90) 명령을 세번만 써서, 매번 호출이 끝나면, 각도가 270이 되서,

다음번 호출시엔 박스모양이 세로로 바껴버리네요.  left(90)을 box함수에 한번더 추가해서 360도가 되도록 맞추도록 하겠습니다.

import turtle as t

def box(x,y,color):
    t.speed('normal')
    t.color(color)
	t.begin_fill()
	t.fd(x)
	t.left(90)
	t.fd(y)
	t.left(90)
	t.fd(x)
	t.left(90)
	t.fd(y)
	t.end_fill()
    t.left(90)      # 90도 회전 명령 추가.
	
#foot
t.penup()
t.goto(-100,-150)
t.pendown()
box(80,50,'blue')

t.penup()
t.goto(0,-150)
t.pendown()
box(80,50,'blue')

input("")

네 이제 발 두개가 완성되었습니다.

이제 각 부분을 이런식으로 다 그려야 하는데, 반복작업이 좀 필요합니다. 그래서 중복작업을 줄이기 위해서, penup(),pendown(),goto()를 모두 box 함수안에 넣고, goto()로 전달될 매개변수를 두개 더 추가하도록 하죠. 귀찮으니깐요.

def box(pos_x,pos_y,x,y,color): #goto()로 전달될 매개변수 pos_x,pos_y 추가.
    t.penup()                #box 함수 안으로 이동
	t.goto(pos_x,pos_y)      #box 함수 안으로 이동, 좌표는 매개변수로 치환.
	t.pendown()              #box 함수 안으로 이동
	t.speed('normal')
	t.color(color)
	t.begin_fill()
	t.fd(x)
	t.left(90)
	t.fd(y)
	t.left(90)
	t.fd(x)
	t.left(90)
	t.fd(y)
	t.left(90)
	t.end_fill()

그다음엔, box 를 호출하는 코드도 수정해주도록 하죠.

#foot
box(-100,-150,80,50,'blue')
box(   0,-150,80,50,'blue')

발을 그리는 명령이 간단해졌죠?

그럼 이런식으로 나머지 부분도 그려주도록 하죠.

 

계속해서 다리도 추가해주겠습니다.

#leg
box(-50,-100,20,100,'red')
box( 50,-100,20,100,'red')

위치를 대충 잡았더니 이렇게 됐네요.

현재 박스의 기준점이 되는 좌표가 왼쪽 아래 모서리이기 때문에, 각 박스별 위치잡기가 애매하고, 좌우 대칭이 되는 그림을 그리기도 힘드네요. 매번 그릴때마다 계산하는것도 귀찮고 하니,  위치를 왼쪽아래로 주는게 아니라, 가운데점으로 인식하도록 하겠습니다.

다시 box() 함수를 바꿔 보도록 하죠. 약간의 산수가 필요합니다.

박스의 가운데점을 pos_x 로 넘겨주면, box함수는 pos_x 로부터 왼쪽으로 x/2 만큼, pos_y로부터 아래로 y/2 만큼 이동해서 왼쪽 아래쪽 점을 찾은다음에 거기서 부터 그림을 그리도록 해주면 됩니다.

def box(pos_x,pos_y,x,y,color):
    t.penup()
	t.goto(pos_x - x/2,pos_y - y/2)  #시작점을 약간의 계산을 통해서 변경.
	t.pendown()
	t.speed('normal')
	t.color(color)
	t.begin_fill()
	t.fd(x)
	t.left(90)
	t.fd(y)
	t.left(90)
	t.fd(x)
	t.left(90)
	t.fd(y)
	t.left(90)
	t.end_fill()
    
#foot
box(-50,-150,80,50,'blue')
box( 50,-150,80,50,'blue')

#leg
box(-50,-100,20,100,'red')
box( 50,-100,20,100,'red')

input("")

이제 좌우 대칭 걱정은 안해도 되겠는데, 위치들만 조금씩 조정해주면 되겠네요. 이런식으로 나머지 부분들도 쭉쭉 그려주겠습니다.

#foot
box(-50,-150,80,50,'blue')
box( 50,-150,80,50,'blue')

#leg
box(-50,-80,20,100,'red')
box( 50,-80,20,100,'red')

#body
box(0,50,150,150,'yellow')

#arm
box(120,70,80,20,'green')
box(-120,70,80,20,'green')

#head
box(0,160,80,70,'pink')

#eye
box(10,170,10,10,'black')
box(-10,170,10,10,'black')

#mouth
box(0,150,30,10,'black')

t.hideturtle()      #커서감추기
input("")

대충 이런그림이 완성됐습니다.

그런데 이 그림을 수정할려면, 매번 좌표와 크기값들을 일일이 수정해야 합니다.

그래서 다음번엔 그 작업을 좀더 효율적으로 할수 있는 방법을 알아보도록 하겠습니다.

댓글

댓글 본문
  1. 김종훈
    구구굿잡
  2. 최윤진
    굿잡!