본문 바로가기

Manual

파이썬 turtle, 함수 사용 꽃 그리기

목차

  1. 함수 
  2. 꽃잎 그리는 함수 만들기
    1. 기본형 꽃잎
    2. 하트형 꽃잎
    3. 역하트형 꽃잎
  3. 꽃 그리는 함수 만들기
  4. 꽃 위치 지정
    1. 위치 지정하기
    2. 위치를 무작위로 정하기
  5. 꽃 색칠하기
    1. 지정한 색을 차례대로 채우기
    2. 무작위로 선정한 색깔로 채우기
  6. 꽃의 크기, 색, 위치 모두 변화 주기

1. 함수

반복해서 사용할 코드를 사용자 정의 함수로 만들어 두면 같은 코드를 다시 작성하지 않고 함수를 불러 사용할 수 있어 편리하다.

  • 함수는 def라는 키워드로 시작한다.
  • def 함수이름( 쉼표(,)로 구분된 매개변수 목록) : 형태로 시작하고
  • 아래에 들여쓰기 하여 반복할 코드를 작성한다.
  • docs.python.org(https://docs.python.org/ko/3/tutorial/controlflow.html#defining-functions)의 사용 예를 보자.
  • 아래와 같이 주어진 수(n)까지 피보나치 수를 출력하는 fib() 함수를 만들고, '2000'보다 작은 피보나치 수를 출력하고 있다.
  • fib 함수는 두 변수 a, b를 차례로 0과 1로 선언하고
  • a를 출력하고, a의 값에 b를, b에는 a+b 한 값을 넣기를 a가 2000 이상이 되기 전까지 반복하는 함수이다.
def fib(n):                           # 함수 정의 시작
    a, b = 0, 1                        # 변수 a와 b에 차례로 0과 1 대입
    while a < n :                    # a 값이 주어진 숫자보다 작으면 계속 반복
        print(a, end = '  ' )     # a 와 공백 출력
        a, b = b, a+b               # a에는 b의 값을, b에는 a와 b를 합친 값을 대입

fib(2000)                           # 함수 실행
<결과> 0  1  1  2  3  5  8  13  21  34  55  89  144  233  377  610  987  1597 

 

 그리는 함수 만들기

함수 만드는 방법과 사용법을 배웠으니, 꽃잎을 그리는 함수를 만들어보자.

     1) 기본형 꽃잎

꽃을 그리기 위해 꽃잎 한 장을 그리고, 꽃잎 한 장 그리는 것을 주어진 숫자만큼 반복해서 꽃을 그리려고 한다.
turtle 모듈을 이용해 아래 그림과 같은 모양의 기본꽃잎을 그리는 함수를 만들자.

< 기본형 꽃잎 >

펜의 움직임을 추적해 보면

  1. 처음 방향에서 왼쪽으로 ∠OAB만큼 회전
  2. AB의 길이만큼 전진
  3. 처음 방향과 맞추기 위해 ∠OAB만큼 오른쪽으로 회전
  4. OB의 길이를 반지름으로 하는 반원을 그린다.
  5. 출발점으로 돌아가기 위해 ∠CAO(=OAB)만큼 오른쪽으로 회전
  6. AC(=AB)의 길이 만큼 전진

AB의 길이를 변수 length, ∠OAB의 크기를 변수 dg에 선언하면, 
OB의 길이는 삼각함수를 이용해 ABsin(dg)로 구할 수 있다.
기본형 꽃잎을 그리는 함수의 이름을 petal이라 하고 사용자 정의 함수를 만들자.

import turtle as t
import math            # 삼각함수를 사용하기 위해 math 모듈 사용

# 초기값 설정
dg = 10                    # 꽃잎 벌림각
length = 200           # 꽃잎의 길이

def petal(dg, length):               # 함수 시작
    t.left(dg)
    t.forward(length)
    c = length*math.sin(math.radians(dg))   # 반지름 계산
    t.right(dg)
    t.circle(-c, 180)
    t.right(dg)
    t.forward(length)

petal(dg, length)      # 함수 실행

《결과》

< petal 함수 실행 결과 >

     2) 하트형 꽃잎

꽃잎의 모양이 하트 모양이 되면 더 아름다운 꽃이 만들어질 것 같다. 하트 모양의 꽃잎을 만드는 petal_heart() 함수를 정의해 보자.

하트 모양 꽃잎은 기본형 꽃잎에서 그리는 반원의 반지름을 반으로 줄이고 두 개를 연속해서 그리면 된다.
펜의 움직임을 추적해 보면

  1. 처음 방향에서 왼쪽으로 일정 각도만큼 회전하고 꽃잎 길이만큼 전진
  2. 처음 방향과 맞추기 위해 일정 각도 만큼 오른쪽으로 회전하고, OB의 길이의 절반을 반지름으로 하는 반원을 그린다.
  3. 펜의 방향을 처음 꽃잎 방향으로 다시 설정하고 반원을 하나 더 그린다.
  4. 출발한 곳으로 돌아가기 위해 일정 각도 만큼 오른쪽으로 회전하고, 꽃잎 길이 만큼 전진
def petal_heart(bd, length, h):
    t.left(dg)
    t.forward(length)
    c = length*math.sin(math.radians(bd))
    t.right(dg)
    t.circle(-c/2, 180)
    t.setheading(h)         # 펜 방향을 처음 꽃잎 방향으로 설정
    t.circle(-c/2, 180)
    t.right(dg)
    t.forward(length)

《결과》

< petal_heart 함수 실행 결과 >

     3) 역하트형 꽃잎

하트형 꽃잎을 변형해 역하트형 꽃잎을 그리는 것도 재미있겠다. 하트형 꽃잎을 그리는 함수에서 반원을 그리는 방향만 반대로 하면 된다. 역하트형 꽃잎을 그리는 함수를 petal_R_heart()라고 정의해 보자.

def petal_R_heart(bd, length, h):
    t.left(dg)
    t.forward(length)
    c = length*math.sin(math.radians(bd))
    t.right(dg)
    t.circle(-c/2, -180)
    t.setheading(h)         # 펜 방향을 처음 꽃잎 방향으로 설정
    t.circle(-c/2, -180)
    t.right(dg)
    t.forward(length)

《결과》

< petal_R_heart 함수 실행 결과 >
petal.py
0.00MB

3. 꽃 그리는 함수 만들기

이제 꽃잎 그리는 함수를 반복하여 꽃을 그리는 함수를 만들자.

  • 꽃잎의 개수(=Np)를 입력받아 꽃잎과 꽃잎 사이의 간격을 정한다. 
  • 꽃잎 그리는 함수를 호출하여 사용한다.
  • 꽃잎 사이의 간격만큼 꽃잎의 방향을 회전하여 새로운 꽃잎을 그린다.
  • 꽃잎의 방향이 360˚ 회전하기까지 반복한다.
Np = 7    # 꽃잎의 수 지정
def make_flower(h, Np):      # 꽃 그리는 함수 시작
     for a in range(0, Np):       # 꽃잎 그리기 반복 횟수 
          petal(dg, length)         # 꽃잎 그리는 함수 호출
          h = h + 360/Np            # 다음 꽃잎을 그리는 각도 계산
          t.setheading(h)            # 다음 꽃잎의 방향 설정

《결과》

< dg=10, length=100, Np=7, h=0, petal() >
< dg=20, length=100, Np=7, h=0, petal_heart() >
< dg=20, length=100, Np=7, h=0, petal_R_heart() >

 

4. 꽃 위치 지정

     1) 위치 지정하기

꽃을 그리는 위치는 setposition(x, y)를 이용하여 지정할 수 있다. 
처음 위치는 x=0, y=0이므로, 왼쪽과 오른쪽으로 각각 어느 정도 떨어진 위치에 그리기 위해서는
x값을 -250, 250으로 하면 되겠다.
꽃을 그리는 함수에 그리는 위치값도 포함시키자.
펜이 이동하는 동안에 선이 그려지면 지저분하게 필요 없는 선이 나타난다.
위치를 이동하는 동안에는 펜을 들게(penup())하고, 그릴 위치에 도착하여 내려놓게(pendown()) 하자. 

def make_flower(h, Np, x, y):    # 지정한 위치에 꽃 그리는 함수
     t.penup()                                # 펜을 들고
     t.setposition(x, y)                  # 지정한 위치로 이동
     for a in range(0, Np):     
          t.pendown()                                 # 펜을 내려 그리기 시작
          petal_R_heart(dg, length, h)          
          h = h + 360/Np
          t.setheading(h)

make_flower(h, Np, -250, 0)
make_flower(h, Np, 0, 0)
make_flower(h, Np, 250, 0)

《결과》

     2) 위치를 무작위로 지정하기

x, y 좌표에 무작위로 고른 숫자를 얻기 위해 random 모듈을 사용한다. 
꽃을 그리는 화면 크기를 고려하여, 일정한 범위 안에서 숫자를 선택하자.
x = random.randint(시작숫자, 끝숫자) 형식으로 사용할 수 있다. 

import random
x = random.randint(-300, 300)
y = random.randint(-200, 200)

무작위로 꽃 3개를 그리도록 for i in range(0, 3): 반복문을 사용하자. 

for i in range(0,3):
     x = random.randint(-300, 300)
     y = random.randint(-200, 200)
     make_flower(h, Np, x, y)

《결과》

< 무작위로 그린 세 개의 꽃 >

 

5. 꽃 색칠하기

fillcolor('색깔') 형식을 사용하여 색을 채울 수 있다. 꽃을 그리는 함수를 수정하자.

def make_flower(h, Np):
     t.fillcolor("purple")       # 색상 지정
     t.begin_fill()                   # 색칠 시작
     for a in range(0, Np):         
          petal_R_heart(dg, length, h)          
          h = h + 360/Np
          t.setheading(h)
     t.end_fill()                      #색칠 끝

《결과》

< purple로 채워진 꽃 >

     1) 지정한 색을  차례대로 채우기 

'파이썬 turtle] 도형을 이용한 꽃 그리기'에서, 사용할 색을 리스트로 지정하고, 리스트 속의 원소(색깔)들을 하나씩 차례대로 불러내어 펜색으로 사용하는 것을 해보았다. 여기서도 같은 방법을 쓰자.

  • 지정할 색을 리스트로 만들기
  • 그려야 할 꽃의 개수가 리스트의 원소로 지정한 색깔 종류보다 많을 때도 반복해서 차례대로 색을 지정할 수 있도록 % 연산자를 활용한다.
Nf = 10                    # 꽃의 수
color_list = [ 'red', 'orange', 'yellow', 'green',  'blue', 'navy', 'purple']
  • make_flower() 함수도 수정
def make_flower(h, Np, x, y, Fcol):
     t.penup()
     t.setposition(x, y)
     t.fillcolor(Fcol)
     t.begin_fill() 
     for a in range(0, Np):
          t.pendown()
          petal_heart(dg, length, h)          
          h = h + 360/Np
          t.setheading(h)
     t.end_fill()   
  • 꽃을 그리는 위치를 선정하는 반복문에 꽃의 색을 지정하는 코드 추가
for i in range(0,Nf):
     x = random.randint(-300, 300)
     y = random.randint(-200, 200)
     Fcol = color_list[i % len(color_list)]  # 꽃 색 선정
     make_flower(h, Np, x, y, Fcol)

《결과》 dg = 20, length = 50, Np = 7, h = 0, Nf = 10 

< 빨, 주, 노, 초, 파, 남, 보, 빨, 주, 노가 그려짐 >

 

     2) 무작위로 선정한 색깔로 채우기

숫자를 사용해 꽃의 색상을 무작위로 지정하기 위해서 칼라모드를 colormode(255)로 설정한다.

t.colormode(255)

꽃을 그리는 반복문에 rgb 색상을 무작위로 배정하는 수식을 추가한다. 밝은 색이 보기 좋아 각 값을 200~255 사이 값으로 제한했다.

     r = random.randint(200, 250)
     g = random.randint(200, 250)
     b = random.randint(200, 250)

마지막으로 꽃을 그리는 함수에서 채우는 색 부분을 수정한다.

def make_flower(h, Np, x, y, r, g, b):
     t.penup()
     t.setposition(x, y)
     t.fillcolor(r, g, b)
     t.begin_fill() 
     for a in range(0, Np):
          t.pendown()
          petal_heart(dg, length, h)          
          h = h + 360/Np
          t.setheading(h)
     t.end_fill()

《결과》 dg = 20, length = 50, Np = 7, h = 0, Nf = 10 

< 제한된 범위 내에서 색상과 위치를 선정해 10개의 꽃을 그림 >
MF-3.py
0.00MB

 

6. 꽃의 크기, 색, 위치 모두 변화 주기

자연 상태의 꽃은 크기에 개체 변이가 있다. 좀 더 자연스럽게 보이게 꽃의 크기도 일정한 범위 안에서 부작위로 선정되게 하자.

     length = random.randint(30, 60)  # 꽃잎의 길이를 30~60 사이로 설정 

꽃의 개수를 많이 그릴 때를 위해 그리는 속도를 빠르게 하자.

  • 펜을 그리지 않게 하고
  • 속도도 빠르게 설정한다.
t.hideturtle()            # 펜을 숨김
t.speed(0)                # 속도를 빠르게 

최종 반복문은 

for i in range(0,Nf):
     x = random.randint(-300, 300)
     y = random.randint(-200, 200)
     r = random.randint(200, 250)
     g = random.randint(200, 250)
     b = random.randint(200, 250)
     length = random.randint(30, 60)  # 꽃잎의 길이를 30~60 사이로 설정 
     
     make_flower(h, Np, x, y, r, g, b)

《결과》 dg = 20, length = 30~60, Np = 7, h = 0, Nf = 200, 하트형 꽃잎

< 크기, 색깔, 위치를 다르게 그린 꽃 200개 >

펜색을 흰색으로 설정하고, 기본형 꽃잎으로 된 꽃을 그려보자.

     t.pencolor(255, 255, 255)                # 펜색 설정 

《결과》 dg = 20, length = 30~60, Np = 7, h = 0, Nf = 100, 기본형 꽃잎

< 펜 색을 흰색으로 바꿈 >
MF-4.py
0.00MB

 

관련_____

파이썬 turtle] 도형을 이용한 꽃 그리기

728x90