Homework 0: Fractal Zoom In

I wrote two fractal shape zooming programs in TaiChi.

  • The first one reproduces the self-similarity of mandelbrot set just like the one on Wikipedia. I set the center of mandelbrot set from -1 to -1.31 and set the radius from 0.5 to 0.12.
# mandelbrot.py
# black 0 < - > 1 white

import taichi as ti
import math

ti.init(arch=ti.cpu)

n = 400  # pixels of | orientation
aspect_ratio = 1
max_iterations = 160  # The more this value is, the figure is finer
pixels = ti.var(dt=ti.f64, shape=(int(aspect_ratio*n), n))


@ti.func
def complex_sqr(z):
    return ti.Vector([z[0]**2 - z[1]**2, z[1] * z[0] * 2])


@ti.kernel
def paint(cx: ti.f32, cy: ti.f32, r: ti.f32):
    for i, j in pixels:  # Parallized over all pixels
        c = ti.Vector([i/n-aspect_ratio/2, j/n-0.5]) * r
        c += ti.Vector([cx, cy], dt=ti.f64)
        z = c
        iterations = 1
        while z.norm() < 4 and iterations < max_iterations:
            z = complex_sqr(z) + c
            iterations += 1
        pixels[i, j] = 1 - iterations / max_iterations


gui = ti.GUI("My Mandelbrot Set", res=(aspect_ratio*n, n))
steps = 100
cx_start, cx_end = -1, -1.31
cx_step = (cx_end - cx_start) / steps
r_start, r_end = 0.5, 0.12
r_step = (r_end - r_start) / steps
for i in range(steps+1):
    # distance from bound to center
    r = r_start + r_step * i
    # x coordinate of center
    cx = cx_start + cx_step*i
    # y coordinate of center
    cy = 0.
    paint(cx, cy, r)
    gui.set_image(pixels)
    # gui.show()
    gui.show("frame/{:04d}.png".format(i))
  • The second one zooms in the Julia set, zooming range from 2 to 1e-7.
# fractal.py
# black 0 < - > 1 white

import taichi as ti
import math

ti.init(arch=ti.cpu)

n = 400
aspect_ratio = 1
max_iterations = 200  # The more this value is, the figure is finer
pixels = ti.var(dt=ti.f64, shape=(aspect_ratio*n, n))


@ti.func
def complex_sqr(z):
    return ti.Vector([z[0]**2 - z[1]**2, z[1] * z[0] * 2])


@ti.kernel
def paint(cx: ti.f64, cy: ti.f64, r:ti.f64):
    for i, j in pixels:  # Parallized over all pixels
        c = ti.Vector([-0.8, 0.2])
        z = ti.Vector([i / n * r - aspect_ratio*0.5*r + cx,
                       j / n * r - 0.5*r + cy])
        iterations = 0
        while z.norm() < 3 and iterations < max_iterations:
            z = complex_sqr(z) + c
            iterations += 1
        pixels[i, j] = 1 - iterations / max_iterations


gui = ti.GUI("My Julia Set Zoom", res=(aspect_ratio*n, n))
steps = 400
r_start, r_end = math.log(2), math.log(1e-7)
r_step = (r_end - r_start) / (steps - 1)
for i in range(steps):
    r = math.exp(r_start + r_step*i)  # radius of x axis
    cx = 1.15497878  # x coordinate of center
    cy = 0.00317400  # y coordinate of center
    paint(cx, cy, r)
    gui.set_image(pixels)
    # gui.show()
    gui.show("frame/{:04d}.png".format(i))

mandelbrot

julia

Looking forward to learning more. Cheers.

9 Likes