본문 바로가기
Lecture

코시 곡선 그리기

by 작은별하나 2011. 9. 24.
반응형

코시 곡선 그리기

 

이 강좌에서는 터틀 그래픽(Turtle Graphic)을 이용하여 프랙탈 중 대표적인 코시 곡선을 화면에 표시한다.

 

터틀 그래픽은 직선을 가지고 그림을 그린다. 현재 위치에서 방향을 결정하고, 해당 방향으로 일정 거리만큼 움직이면, 그 궤적이 하나의 그림이 된다. 마치 거북이가 지나간 궤적이 하나의 그림이 되는 것처럼 동작한다.

 

제일 먼저 Visual studio에서 win32 어플리케이션을 선택하여 프로젝트를 만든다. 이 때, 빈 프로젝트가 아닌 기본 프로그램이 있는 상태로 만든다.

 

터틀 그래픽을 구현하기 위해서는 사인(sine) 함수와 코사인(cosine) 함수와 같은 삼각함수가 사용되므로 math.h 헤더 파일을 소스에 포함하여야 한다. 아래 소스와 같이 math.h를 포함하도록 한다.


#include "stdafx.h"
#include "resource.h"
#include <math.h>

[포함파일들]


터틀 그래픽에서 그림을 그리는 도구가 되는 클래스를 추가하도록 한다. CTurtle 클래스는 지역변수로 생성하여 사용하도록 설계하였다. 생성자에서는 디바이스 컨텍스트를 설정한다. MoveTo 함수는 거북이의 위치를 지정된 위치로 옮겨준다. Draw 함수는 거북이를 현재 방향으로 정해진 거리만큼 이동하며 그림을 그리도록 한다. TurnLeft 함수와 TurnRight 함수는 거북이의 방향을 바꾸어준다.


#define MAX_LOADSTRING 100

class CTurtle
{
public:
    CTurtle( HDC dc ) { m_hDC = dc; }
    ~CTurtle() { }

    void MoveTo( float x, float y, float degree ) { m_fX = x; m_fY = y; m_fDegree = degree; }
    void Draw( float length )
    {
        MoveToEx(m_hDC, (int)m_fX, (int)m_fY, NULL);
        m_fX += length * (float)cos( m_fDegree * 3.141592 / 180.0 );
        m_fY -= length * (float)sin( m_fDegree * 3.141592 / 180.0 );
        LineTo( m_hDC, (int)m_fX, (int)m_fY);
    }
    void TurnLeft( float degree ) { m_fDegree += degree; }
    void TurnRight( float degree ) { m_fDegree -= degree; }

private:
    // Graphic Device Context
    HDC m_hDC;
    // Current Position
    float m_fX, m_fY;
    float m_fDegree;
};

// Global Variables:
HINSTANCE hInst;                // current instance
TCHAR szTitle[MAX_LOADSTRING];        // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];    // The title bar text

[CTurtle 클래스 설계 및 기타 변수 설정] 

다음 그림은 선형 프랙탈의 일종인 코시 곡선이다. 위에서 만든 터틀 그래픽 도구를 사용하여 코시 곡선을 만들어보도록 하자.

 

 

Koch 함수는 재귀함수로 구성하였다. 전달 파라미터는 그림을 그리기 위한 터틀 그래픽 오브젝트, 그려질 길이, 그리고 그려질 깊이로 구성되었다. Koch 함수의 프로토 타입을 다음 소스와 같이 추가하였다.


  

// Foward declarations of functions included in this code module:
ATOM            MyRegisterClass(HINSTANCE hInstance);
BOOL            InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
void Koch( CTurtle &turtle, float length, int depth );

[함수 프로토 타입 선언]

 

다음 소스는 Koch 함수의 본문이다. 깊이 값인 depth가 0인 경우에 그림을 그리며, 그렇지 않으면 깊이 값을 줄여서 Koch 함수를 재귀 호출한다.


void Koch( CTurtle &turtle, float length, int depth )
{
    if( depth == 0 )
    {
        turtle.Draw( length );
        return;
    }
    Koch( turtle, length/3.0f, depth-1 );
    turtle.TurnLeft( 60.0f );
    Koch( turtle, length/3.0f, depth-1 );
    turtle.TurnRight( 120.0f );
    Koch( turtle, length/3.0f, depth-1 );
    turtle.TurnLeft( 60.0f );
    Koch( turtle, length/3.0f, depth-1 );
}

[koch 함수 작성]

실제 그림을 그리기 위해서 WM_PAINT 메시지 처리 루틴에 작성하도록 한다. 이 작업을 마치면 프로그램이 모두 완성된다.


       case WM_PAINT:
       {
            hdc = BeginPaint(hWnd, &ps);
            RECT rt;
            GetClientRect(hWnd, &rt);
            CTurtle turtle( hdc );
            turtle.MoveTo( rt.left+10.0f, rt.bottom-10.0f, 0.0f );
            Koch( turtle, rt.right-rt.left-20.0f, 5 );
            break;
        }

[WM_PAINT 메세지 수신부 수정] 

728x90

'Lecture' 카테고리의 다른 글

3. Unity3D에서 간단한 C# 스크립트 만들기  (0) 2014.04.22
Unity3D의 GameObject 객체 소개  (0) 2014.03.18
Unity3D의 Monobehaviour 클래스 소개  (2) 2014.03.18
Unity3D와 NGUI 소개 및 설치  (0) 2014.03.17
목차  (0) 2014.03.17

댓글