# 재귀적 프랙탈

프랙탈의 기본 속성은 자기유사성(Self-Similarity)과 순환성(Recursiveness)으로, 프랙탈의 순환성을 구현하는 가장 원시적인 방법은 함수의 재귀호출을 이용하는 방법이다. 이에 의한 프랙탈은 있는 그대로 따져 만들어진다.

## 함수의 재귀호출

함수 실행 중 자기자신을 다시 호출하는 것을 재귀호출(Recursive Call)이라 한다. 재귀호출을 순환호출이라고도 한다. 다으에 재귀호출 함수를 사용한 프로그램예를 표시하였다. 이 프로그램에서 RecursiveFunc() 함수는 재귀호출 방식으로 실행된다. 즉 RecursiveFunc() 내부에서 다시 RecursiveFunc() 를 실행시키고 있다.

```c
void RecursiveFunc(int n)
{
    if( n != 3 )
        RecursiveFunc(n+1);

    printf("%-3d", n);
}

int main(void)
{
    RecursivFunc(0);
    return 0;
}
```

재귀 호출의 자세한 내용은 참고 문헌을 참고하거나 기타 알고리즘 서적을 참고하길 바란다.

## 예제 프랙탈

다음 코드는 맛보기 프로그램을 표시한 것이다. RecursiveCircle() 함수, 코드는 불과 5 줄이다. 그런데 만들어내는 결과는 무시무시하다. 재귀호출 함수 인자의 '마법의 피리'에 의한 연출이다.

![](/files/-M3x20NAfm_qXHkGKRDQ)

```cpp
#include "lib\egl.h"
#include <math.h>

using namespace egl;

#define TORAD (0.01745f)

void DrawCircle(GLfloat x, GLfloat y, GLfloat r)
{
    glBegin(GL_POINTS);
        for(int i=0; i<360; ++i)
        {
            glVertex2f(x+(r*cos(i*TORAD)), y+(r*sin(i*TORAD)));
        }
    glEnd();
}

void RecursiveCircle(GLfloat x, GLfloat y, GLfloat r)
{
    if(r>1.0f)
    {
        DrawCircle(x, y, r);
        RecursiveCircle(x-r/2, y, r/2); /* x:r/2 감소, r:1/2감소 */
        RecursiveCircle(x+r/2, y, r/2); /* x:r/2 증가, r:1/2감수 */
    }
}

class RenderWindow : public Window
{
public:
    virtual void RenderGLScene(void);
};

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

    glTranslatef(0.0f, 0.0f, -100.0f);
    glColor3f(1.0f, 0.0f, 0.0f);
    RecursiveCircle(0.0f, 0.0f, 30.0f);
}

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

RecursiveCircle() 함수가 어떻게 위의 그림을 그려내는지 가물가물하다면 참고 문헌을 참고한다. 아주 자세한 설명이 적혀 있다. ;] RecursiveCircle() 의 함수 내용을 조금씩 바꿔 보면서 결과를 보자.

![](/files/-M3x20NEsYjYwdxiuKsk)

```cpp
void RecursiveCircle(GLfloat x, GLfloat y, GLfloat r)
{
    if(r>1.0f)
    {
        DrawCircle(x, y, r);

        RecursiveCircle(x-r/2, y, r/2);
        RecursiveCircle(x+r/2, y, r/2);
        RecursiveCircle(x, y-r/2, r/2);
        RecursiveCircle(x, y+r/2, r/2);
    }
}
```

![](/files/-M3x20NI2rSnxbLhVLpm)

```cpp
void RecursiveCircle(GLfloat x, GLfloat y, GLfloat r)
{
    if(r>8.0f)
    {
        DrawCircle(x, y, r/2);

        RecursiveCircle(x-r/2, y, r/2);
        RecursiveCircle(x+r/2, y, r/2);
        RecursiveCircle(x, y-r/2, r/2);
        RecursiveCircle(x, y+r/2, r/2);
    }
}
```

![](/files/-M3x20NKKr_f9ADBwY86)

```cpp
void RecursiveCircle(GLfloat x, GLfloat y, GLfloat r)
{
    if(r>1.0f)
    {
        if(r<=10.0f)
        {
            glColor3f(0.0f, 0.5f, 0.0f);
        }
        else if(r<=30.0f)
        {
            glColor3f(1.0f, 1.0f, 0.0f);
        }
        else if(r<=50.0f)
        {
            glColor3f(1.0f, 0.0f, 1.0f);
        }
        DrawCircle(x, y, r);
        RecursiveCircle(x-r/2, y, r*0.4);
        RecursiveCircle(x+r/2, y, r*0.4);
        RecursiveCircle(x, y-r/2, r*0.4);
        RecursiveCircle(x, y+r/2, r*0.4);
    }
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://sungcheol-kim.gitbook.io/fractal-graphics-with-opengl/chapter2.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
