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

Was this helpful?

C곡선

Previous코호섬Next드래곤 곡선

Last updated 5 years ago

Was this helpful?

아래와 같은 모양의 곡선을 C 곡선이라 한다. 모양이 영문자 'C' 와 닮았기 때문이다. 언뜻 아래와 같은 프랙탈을 만드는 것은 아주 어려울 것 같은 생각이 들 수도 있겠으나 거북이 그래픽과 재귀호출을 사용하면 믿어지지 않을 정도로 간단히 만들 수 있다.

알고리즘

  1. 왼쪽으로 45 도 회전하여 선을 그린다.

  2. 오른쪽으로 90 도 회전하여 선을 그린다.

  3. 왼쪽으로 45 도 회전하여 전진 방향을 원래대로 돌려놓는다.

위의 알고리즘을 코드로 표현하면 아래와 같다.

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

C 곡선의 알고리즘은 단순하다. 왼쪽으로 45 도 돌고 전진하고 오른쪽으로 90 도 돌고 전진하고 왼쪽으로 45 도 돈다. 이 단순한 알고리즘이 재귀적으로 반복하여 위와 같은 그림이 그려진다니 믿어지지 않을 정도이다. 재귀호출의 마력이다. 아래는 C 곡선을 구현한 프로그램의 실행 결과와 전체 코드다. 코드 중에 C 곡선 함수 구현 중 glFlush() 와 SwapBuffer() 함수가 있는데 이는 재귀 함수의 수행이 너무 길어질 경우 결과를 보려면 많은 시간을 기다려야 한다. 하지마 위의 함수를 호출해 주면 프랙탈이 그려지는 과정을 바로바로 볼 수 있게 된다.

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

using namespace egl;

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

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::c_curve(int n)
{
    if(n == 0)
    {
        turtle.Forward(1.0f);
        glFlush();
        SwapBuffers(mDC);
    }
    else
    {
        turtle.Left(45); c_curve(n-1);
        turtle.Right(90); c_curve(n-1);
        turtle.Left(45); 
    }
}

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

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

    turtle.SetStartPoint(-90.0f, 0.0f, 0.0f);
    c_curve(15);
}

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