거북이 그래픽(Turtle Graphic) 은 그래픽스의 여러 분야에서 두루 활용된다. 프랙탈 분야에서도 예외가 아니어서 많은 프랙탈이 거북이 그래픽을 응용하고 있다. 그 대표적인 예가 나중에 다룰 L-SYSTEM 이다. 거북이 그래픽스에 대해 궁금한 사항은 다음 링크된 참고 문서를 참고한다.
코호 곡선에 대해서 자세히 알아보기 전에 우리가 사용할 거북이 그래픽 클래스에 대해서 알아보자. 거북이 그래픽은 모래사장 위에서 거북이가 지나간 자리에 자국이 남듯이 캔바스 위에서 전진과 회전만을 적용해 그림을 그리는 것이다. 이 거북이 그래픽 클래스에서는 전진(Forward) 와 회전을 지원하고 회전을 왼쪽 회전과 오른쪽 회전으로 나누어 작성했다. 다음은 이 거북이 그래픽의 클래스 전 코드와 간단한 예제를 실행한 모습이다. 물론 지금 작성한 거북이 그래픽 클래스는 OpenGL 상에서 올바르게 작동한다.
// Header File#ifndef_TURTLE_H_#define_TURTLE_H_#include<vector>#defineTORAD0.01745f //각도를 라디안으로 바꾸기 위한 (3.14152/180) 의 값 //거북이가 지나간 지점의 좌표를 기억하기 위한 자료structPoint3D{float x, y, z;Point3D() { x=y=z=0.0f; }Point3D(constPoint3D& pt) { x=pt.x; y=pt.y; z=pt.z; }Point3D(float ax,float ay,float az) { x=ax; y=ay; z=az;}};usingnamespace std;typedef vector<Point3D> plist; //Point3D 를 담는 vector 컨테이너typedef vector<Point3D>::iterator pi; //반복자classTurtle{private: plist PointList; //거북이가 지나간 모든 지점을 저장할 컨테이너bool IsUp; //현재 거북이가 들려있는지. 즉, 현재 거북이가 들려 있다면 선은 그려지지 않는다. float angle; //회전 각도public:Turtle(void); //거북이 생성voidSetStartPoint(float x,float y,float z); //거북이가 출발할 시작 위치 좌표voidForward(float length); //앞으로 몇 length 만큼 진행하는가? 진행 거리만큼 선을 그린다. 단 IsUp == false 일 때만.voidLeft(float rotate_angle); //왼쪽으로 rotate_angle 만큼 회전한다. voidRight(float rotate_angle); //오른쪽으로 rotate_angle 만큼 회전한다.voidUp(void); //거북이를 든다.voidDown(void); //거북이를 내려 놓는다.voidMarkPoint(void); //거북이가 지나간 모든 지점을 점으로 표시한다.};#endif
1904년 코호에 의해 발표된 곡선이다. 외관은 곡선처럼 보이나 곡선내의 어떤 부분도 '구불어진 곡선'은 포함하고 있지 않고 직선의 연결로만 되어 있다. 선의 총 길이는 무한대이다. 발표 당시에는 전혀 주목을 받지 못하다가 70여년이 흘러 만델브로트에 의해 프랙탈이 등장한 후 화려하게 복권되어, 이제는 프랙탈에 관한 어떤 책에서나 빠짐없이 등장한다.
알고리즘
코호 곡선은 완벽한 재귀적 구조로 되어 있다. 기본 도형은 직선이다. 직선에서 시작하여 다음과 같은 알고리즘으로 그려지게 된다.
직선을 그린다.
왼쪽으로 60 도 회전하여 직선을 그린다.
오른쪽으로 120 도 회전하여 직선을 그린다.
왼쪽으로 60 도 회전하여 직선을 그린다.
재귀호출이 한번 반복될 때마다 차수를 1씩 줄이고(n -> n-1), 차수가 0 이 되면 선을 그리면 된다. 다음은 이 알고리즘을 코드로 표현한 것이다.
차수 n=1 인 경우를 생각해 보자. 처음에는 n=1 이고 따라서 if...else { ... } 의 { ... } 부분이 실행되어 위에서 설명한 알고리즘대로 방향을 회전시키면서 Koch() 함수가 4차례 재귀호출된다. Koch(n-1) 은 Koch(1-1) 로 실행되고 이때에는 n=0 이므로 if(n==0) turtle.Forward() 함수가 실행되어 직선을 그리고 직선 끝으로 이동한다. else { ... } 의 4 개의 Koch() 함수가 실행되고나면 위에서 위의 그림 중 직선 옆의 가운데 그림처럼 선이 그려진다.