이 글에서는 망델브로 집합의 정의를 설명하고, CindyJS로 간단히 그려내는 법을 안내하겠습니다.

망델브로 집합은 복소수에서 정의된 수열 $z_0 = 0$, $z_{n+1} = z_n^2 +c $이 수렴하도록 하는 복소수 $c$들의 집합인데, 복소평면에 그려 보면 다음과 같은 모양을 하고 있습니다.


이 그림을 그리기 위해서 수열을 무한 번 계산해 볼 수는 없으므로 수렴조건을 먼저 파악해 보기로 합니다.

우선, 삼각부등식에 의해 $$|z_{n+1}| = | z_n^2 +c | \geq |z_n|^2 -|c|$$ 라는 식을 얻을 수 있는데, $|z_n| > |c|$일 때는 이 부등식이 다음과 같이 정리됩니다. $$|z_{n+1} | \geq |z_n|^2 -|z_n| = |z_n| (|z_n|-1)$$ 그래서, 만약 $|z_n|>2$까지도 성립한다면, 즉, $|z_n| > \max \{2, |c|\}$가 성립한다면 위 부등식과 함께 $|z_{n+1}| \geq |z_n|$을 얻고, 이 결과로 $$|z_{n+2} | \geq |z_{n+1}|(|z_{n+1}|-1) \geq |z_{n+1}|(|z_n|-1)$$ 이라는 부등식을 얻습니다. 즉 $p \geq n$이면 $$|z_{p+1} | \geq |z_p| (|z_n|-1)$$ 이 되므로 $|z_n| > \max \{ 2, |c| \}$을 만족하는 항이 하나라도 있는 수열은 발산합니다. 그런데, 애초에 $|c|>2$인 경우에는 위와 같은 논리로 $$|z_{n+1}| \geq |z_n| (|c|-1)$$ 이 되어 발산하게 되므로 $|c| \leq 2$인 부분만 계산하면 됩니다. 즉, 수렴조건은 $|z_n| \leq 2$라 설정하면 됩니다.

이제, 이 내용을 CindyJS로 만들어보겠습니다. 다른 언어와 달리 CindyJS는 입력방법이 간단합니다. (CindyJS를 처음 접하시는 분은 여기를 클릭해서 간단한 정보를 얻으시기 바랍니다.)

<!doctype html>
<html>
      
<head>
  <script type="text/javascript" src="js/Cindy.js"></script>
</head>
      
<body>

  <div id='CSCanvas'></div>
       
  <script id='csdraw' type='text/x-cindyscript'>
    colorplot(
      c = complex(#);
      z = 0;
      repeat(100,
        if(abs(z)<=2, z=z^2+c);
      );
      gray(abs(z)/2);
    );
  </script>
  <script>
    CindyJS({
      scripts: 'cs*',
      autoplay: true,
      ports: [{
        id: 'CSCanvas',
        width: 500,
        height: 500,
        transform: [{
          visibleRect: [-2, 2, 2, -2]
        }]
      }]
    })
  </script>
</body>
      
</html>
  

14번에서 20번 내용을 빼고 나머지 부분은 CindyJS를 작성할 때 항상 쓰는 부분이므로 이 7개 줄만으로 Mandelbrot Set이 그려진다는 것을 알 수 있습니다. 14번 줄은 캔버스의 모든 픽셀을 복소수값으로 설정한 부분입니다. 17째 줄은 수렴조건을 만족하는 부분에서만 추가계산을 하도록 설정한 부분이고요, 그림은 19번 줄에서 그려집니다. 이렇게 얻어진 html 파일을 브라우저로 읽으면 다음과 같은 그림이 그려집니다.


특히, 위 소스에는 발산하는 순간에 계산된 $z$의 값이 저장되어 있으므로 색칠하는 부분을 gray가 아닌 hue를 사용해 다음과 같이 바꾸면 (19번 줄)중간과정도 살펴볼 수 있습니다.

<!doctype html>
<html>
      
<head>
  <script type="text/javascript" src="js/Cindy.js"></script>
</head>
      
<body>

  <div id='CSCanvas'></div>
       
  <script id='csdraw' type='text/x-cindyscript'>
    colorplot(
      c = complex(#);
      z = 0;
      repeat(100,
        if(abs(z)<=2, z=z^2+c);
      );
      hue(arctan2(z)/2/pi);
    );
  </script>
  <script>
    CindyJS({
      scripts: 'cs*',
      autoplay: true,
      ports: [{
        id: 'CSCanvas',
        width: 500,
        height: 500,
        transform: [{
          visibleRect: [-2, 2, 2, -2]
        }]
      }]
    })
  </script>
</body>
      
</html>
  

위 파일을 읽어들이면 다음과 같은 그림이 나옵니다.

또한, 17번 줄의 지수를 바꿔가면서 달라지는 모습을 관찰할 수도 있습니다. 아래 그림은 $z_{n+1} = z_n^6 +c$인 경우를 그린 것입니다.


+ Recent posts