코흐 커브(Koch Curve)
코흐 커브는 1904년 스웨덴의 수학자 코흐에 의해서 제안된 프랙털1 커브(fractal curve)를 의미합니다. 이러한 코흐 커브를 생성하는 것을 오늘은 제작해보도록 하겠습니다.
거북이 그래픽
거북이 그래픽(Turtle Graphic)은 1967년에 디자인된 교육용 프로그래밍 언어입니다. 이는 그래픽을 그리기 위한 간단한 프로그램으로 거북이가 펜을 의미하고 이러한 거북이가 가는 길이 그래픽 객체가 됩니다. 그림 그리기를 원한다면 파이썬을 사용하면 됩니다. 파이썬에서 아래의 코드를 사용해서 그릴 수 있습니다.
from turtle import Pen
t = Pen()
t.forward(100)
아래는 사각형을 그리는 예제입니다.
from turtle import Turtle
t = Turtle()
for n in range(4):
t.forward(50)
t.left(90)
이것의 실행 결과는 아래와 같이 나타납니다.
인터프리터를 만들어 봅시다.
우리는 코흐 커브를 간단한 명령어를 바탕으로 즉석에서 만드는 인터프리터를 만들 것입니다. 명령어 F는 거북이 전진을 L은 거북이의 정면 기준 좌측 60도 회전을 R은 우측 120도 회전을 하는 기능으로 만들 것입니다. 이를 BNF(Backus-Naur Form)2을 사용해서 표현하면 아래와 같이 표현할 수 있습니다.
<program> ::= <instruction> <program>
| <instruction>
<instruction> ::= 'F' | 'L' | 'R'
인터프리터의 역할은 2가지를 할 것입니다.
- 코흐 프로그램을 받아들여서 실행하도록 할 것입니다.
- 실행 결과 코흐 커브를 그리도록 할 것입니다.
인터프리터는 엔진과 드라이버의 2가지 부분으로 나뉩니다. 그리고 드라이버는 작업을 가져오는 기능을 하고 엔진은 소스 프로그램을 해석하는 기능을 합니다.
엔진은 아래와 같이 작성할 수 있습니다.
from turtle import *
def interpret(pgm):
t = Turtle()
for instr in pgm:
if instr == 'F':
t.forward(10)
elif instr == 'L':
t.left(60)
elif instr == 'R':
t.right(120)
else:
print('Syntax error near "{}"'.format(instr))
t.hideturtle()
exitonclick()
그리고 드라이버 프로그램은 아래와 같이 작성 가능합니다.
import sys
if len(sys.argv) < 2:
print('Usage: {} {}'.format(sys.argv[0], 'Koch_pgm'))
else:
infile = open(sys.argv[1],'r')
pgm = infile.readline().strip()
interpret(pgm)
infile.close()
컴파일러를 만들어 봅시다.
이번에는 인터프리터 방식이 아니라 컴파일러 방식으로 제작해보도록 하겠습니다. 컴파일러는 코흐 프로그램을 받아들이고, 코흐 커브를 그리는 파이썬 프로그램을 생성할 것입니다. 코흐 프로그램이 원시 프로그램이고, 파이썬 프로그램이 목표 프로그램이 됩니다.
이러한 컴파일러는 머리말(prologue), 끝말(epilogue)에 의해서 코드가 설정이 되고, 드라이버 코드는 작업을 가져오는 기능을 하고 수행합니다. 컴파일러의 엔진은 원시 코드에서 목표 코드를 생성하는 일을 합니다.
먼저 설정 코드입니다. 머리말에서는 런타임 환경을 설정을 해주도록 합니다.
prologue = '''
from turtle import *
def main():
t = Turtle()
'''
다음으로 끝말입니다. 끝말에서는 실행 이후 해야 할 작업을 가져오도록 설정합니다.
epilogue = '''
t.hideturtle()
exitonclick()
main()
'''
이에 따른 드라이버 코드는 아래와 같이 제작 할 수 있습니다.
import sys
if len(sys.argv) < 2:
print('Usage: {} {}'.format(sys.argv[0], 'Koch_pgm'))
else:
ifile = open(sys.argv[1],'r')
ofile = open('a.py', 'w')
pgm = ifile.readline().strip()
ofile.write(prologue)
translate(ofile, pgm)
ofile.write(epilogue)
ofile.close()
ifile.close()
엔진은 직접 제작해볼 수 있도록 남기도록 하겠습니다.