[42-Seoul/fract-ol] Mandelbrot Set

yebeen·2022년 8월 8일
0

42-Seoul/fract-ol

목록 보기
3/4
post-thumbnail

망델브로 집합 (Mandelbrot set)

수열[Zn]의 절댓값이 무한대로 발산하지 않는 복소수 c의 집합으로 정의됩니다.

z0=0(,zn은복소수)z_0 = 0 (단, z_n은 복소수)

zn+1=zn2+cz_{n+1} = z_n^2+c

이를 복소수를 사용하지 않고 정의하려면 모든 복소수를 실수부와 허수부로 나누면 됩니다. znz_nxnynx_ny_n로, c를 (a, b)로 바꾸면 아래와 같은 식을 얻을 수 있습니다.

(x0y0)=(0,0)(x_0y_0) = (0,0)

xn+1=xn2yn2+ax_{n+1} = x_n^2 - y_n^2 + a

yn+1=2xnyn+b(,xn,yn,a,b는실수)y_{n+1} = 2x_ny_n + b (단, x_n, y_n, a, b는 실수)

실제로 무한한 항까지 계산하여 발산 여부를 확인하는 것이 어려우므로 어떤 n에 대해 |Zn| > 2일 경우 발산한다는 성질을 이용합니다. 즉, 수열을 계산하다가 절댓값이 2를 넘는 점은 배제하고 그리면 되는 것입니다. 수학적으로는 어떤 점이 망델브로 집합에 포함되거나 포함되지 않거나의 두 가지 경우밖에 없으므로 흑백으로만 그래도 상관은 없지만 대부분의 경우 처음으로 |Zn| > 2를 넘는 경우 배경을 칠합니다.

위 식을 이용하여 망델브로 집합 코드를 작성했습니다.

void ft_mandelbrot(t_complex c, t_fractol *f)
{
	int 		i;
	t_complex 	z;
	double 		tmpx;

	z.x = c.x;
	z.y = c.y;
	i = 0;
	while (i < ITERATION && (z.x * z.x) + (z.y * z.y) < 4)
        {
		tmpx = (z.x * z.x) - (z.y * z.y);
		z.y = (2 * z.x * z.y) + c.y;
		z.x = tmpx + c.x;
		i++;
	}
}

쥘리아 집합 (Julia set)

복소수 c에 대해서 다음 점화식에 따라 정의된 수열이 발산하지 않는 성질을 갖도록 하는 복소수 z의 집합으로 정의됩니다.

zn+1=zn2+cz_{n+1} = z_n^2 + c

만델브로 집합의 점화식과 같지만, 만델브로 집합은 z0=0+0iz_0 = 0+0_i일 때 z를 발산하지 않게 하는 c의 집합이라는 점이 다릅니다. 즉, 망델브로 집합과 쥘리아 집합은 z와 c의 역할이 뒤바뀐 것입니다. 또한 쥘리아 집합은 망델브로 집합과 동일하게 자기 유사성을 가지며 가까운 두 점이 서로 다른 양상을 보이는 초기 조건의 민감성도 가집니다.

(x0y0)=(0,0)(x_0y_0) = (0,0)

xn+1=xn2yn2+ax_{n+1} = x_n^2 - y_n^2 + a

yn+1=2xnyn+b(,xn,yn,a,b는실수)y_{n+1} = 2x_ny_n + b (단, x_n, y_n, a, b는 실수)

void	ft_julia(t_complex c, t_fractol *f)
{
	t_complex	z;
	double		tmp;
	int			i;

	i = 0;
	z.x = c.x;
	z.y = c.y;
	while (i < ITERATION && (z.x * z.x) + (z.y * z.y) < 4)
	{
		tmp = z.x;
		z.x = (z.x * z.x) - (z.y * z.y) + f->julia.x;
		z.y = (2 * tmp * z.y) + f->julia.y;
		i++;
	}
	f->i = i;
}

불타는 배 프랙탈 (Burning Ship fractal)

xn+1=xn2yn2+ax_{n+1} = x_n^2 - y_n^2 + a

yn+1=2xnyn+b(,xn,yn,a,b는실수)y_{n+1} = 2 |x_n y_n| + b (단, x_n, y_n, a, b는 실수)

void ft_mandelbrot(t_complex c, t_fractol *f)
{
	int 		i;
	t_complex 	z;
	double 		tmpy;

	z.x = c.x;
	z.y = c.y;
	i = 0;
	while (i < ITERATION && (z.x * z.x) + (z.y * z.y) < 4)
        {
            tmpy = (z.x * z.y);
            z.x = (z.x * z.x) - (z.y * z.y) + c.x;
            z.y = 2 * abs(tmpy) + c.y;
            i++;
	}
}
profile
🐣🐥

0개의 댓글