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))
Looking forward to learning more. Cheers.