🔺
Fractal Graphics With OpenGL
  • Introduction
  • 저자 소개
  • Fractal에 대하여
  • 재귀적 프랙탈
  • 칸토어 먼지
  • 시어핀스키 양탄자
  • 코호 곡선
  • 코호섬
  • C곡선
  • 드래곤 곡선
  • 이진 나무
  • L-SYSTEM
  • L-SYSTEM 을 활용한 프랙탈
  • 부록 : 거북이 그래픽스의 이해
Powered by GitBook
On this page

Was this helpful?

드래곤 곡선

PreviousC곡선Next이진 나무

Last updated 5 years ago

Was this helpful?

C 곡선의 알고리즘을 조금만 수정하면 아래와 같은 프랙탈을 얻을 수 있다. 모양이 대충 용 비슷하다. 그래서 이름이 드래곤 곡선이다. 아래의 그림은 각각의 차수가 10 과 15인 그림이다.

알고리즘

드래곤 곡선은 차수 1 의 C 곡선을 위, 아래로 번갈아 가면서 그리는 알고리즘을 사용한다.

  • 드래곤 곡선 위를 그리는 알고리즘

    1. 왼쪽으로 45 도 회전한다.

    2. 드래곤 곡선의 윗부분의 루틴을 호출한다.

    3. 오른쪽으로 90도 회전한다.

    4. 드래곤 곡선을 아랫부분의 루틴을 호출한다.

    5. 왼쪽으로 45 도 회전한다.

  • 드래곤 곡선 아래를 그리는 알고리즘

    1. 오른쪽으로 45 도 회전한다.

    2. 드래곤 곡선의 윗부분의 루틴을 호출한다.

    3. 왼쪽으로 90 도 회전한다.

    4. 드래곤 곡선의 아랫부분의 루틴을 호출한다.

    5. 오른쪽으로 45 도 회전한다.

아래는 위의 알고리즘을 코드로 표현한 것이다.

//드래곤 곡선의 윗부분을 그린다.
void DragonCurve_up(int n)
{
    if(n==0)
    {
        turtle.Forward(1.0f);
    }
    else
    {
        turtle.Left(45); DragonCurve_up(n-1);
        turtle.Right(90); DragonCurve_down(n-1);
        turtle.Left(45);
    }
}

//드래곤 곡선의 아랫부분을 그린다.
void DragonCurve_down(int n)
{
    if(n==0)
    {
        turtle.Forward(1.0f);
    }
    else
    {
        turtle.Right(45); DragonCurve_up(n-1);
        turtle.Left(90); DragonCurve_down(n-1);
        turtle.Right(45);
    }
}

드래곤 곡선은 양방향 재귀성이다. DragonCurve_up() 내에서 DragonCurve_down() 을 부르고, DragonCurve_up() 도 재귀적으로 돌고 DragonCurve_down() 도 재귀적으로 돈다. 아래는 드래곤 곡선을 구현한 프로그램 결과와 전체 코드이다. 색상이 들어가 있는 그림은 거북이가 이동한 점을 표시해 본 것이다.

#include "lib\egl.h"
#include "turtle.h"

using namespace egl;

class RenderWindow : public Window
{
private:
    Turtle turtle;
public:
    void DragonCurve_up(int n);
    void DragonCurve_down(int n);
    virtual void RenderGLScene(void);
    virtual void OnSize(WPARAM wParam, LPARAM lParam);
};

void RenderWindow::DragonCurve_up(int n)
{
    if(n==0)
    {
        turtle.Forward(1.0f);
    }
    else
    {
        turtle.Left(45); DragonCurve_up(n-1);
        turtle.Right(90); DragonCurve_down(n-1);
        turtle.Left(45);
    }
}

void RenderWindow::DragonCurve_down(int n)
{
    if(n==0)
    {
        turtle.Forward(1.0f);
    }
    else
    {
        turtle.Right(45); DragonCurve_up(n-1);
        turtle.Left(90); DragonCurve_down(n-1);
        turtle.Right(45);
    }
}

void RenderWindow::OnSize(WPARAM wParam, LPARAM lParam)
{
    GLsizei width = LOWORD(lParam);
    GLsizei height = HIWORD(lParam);

    if (height == 0)
        height = 1; 

    glViewport( 0, 0, width, height ); 

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 

    gluPerspective(54.0f, GLfloat(width)/GLfloat(height), 1.0f, 1000.0f);

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
}

void RenderWindow::RenderGLScene(void)
{
    Window::RenderGLScene();

    glTranslatef(0.0f, 0.0f, -300.0f);

    turtle.SetStartPoint(-35.0f, 0.0f, 0.0f);
    DragonCurve_up(15);
    turtle.MarkPoint();
}

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    RenderWindow app;
    if(!app.Create(FALSE, "Fractal - Dragon Curve",330,260))
        return EXIT_FAILURE;
    return app.Run();
}