What I’m working on right now…

I’ve been experimenting with creating fractal images using iterating functions of the form

z_{n+1} = \frac{z_n^a + c}{z_n^b - c}
z_0 = 0.

Without getting into all the details right now, within each frame of the animation every pixel represents a different value of the complex variable c. For a given value of c, the number of iterations required for the magnitude of z_n to pass a pre-defined threshold determines the colour of the corresponding pixel. If the sequence exceeds the limit within a small number of iterations, the pixel will be white. Conversely, if the magnitude of z_n remains within the threshold until the maximum number of iterations is reached, the pixel ends up black.

In the following animation, a remains constant (a=5.0) from frame to frame while b is incremented in steps of 0.01 from 0.0 to 4.0. The region of the complex plane shown is -2 < Re{c} < 0 and 0 < Im{c} < 2.

I used the following Python script to generate the individual frames of the animation:

# fractal_movie.py - Written by Ted Burke, last updated 7-1-2016

import subprocess
import math

centre = 0 + 2j   # complex value at centre of image
w,h = 800,400     # image width and height
pxw = 0.01        # pixel width
limit = 4.0       # once z reaches this value, iteration ceases

# Create a buffer to store a row of pixel values
row = w*[0]

# Create fractal image files
for t in range(401):
    a = 5
    b = t/100.0
    # Open file
    pgmfilename = 'crpf_a{:1.3f}_b{:1.3f}_pxw{:.3f}_lim{:1.1f}_{:d}x{:d}px.pgm'.format(a, b, pxw, limit, w, h)
    pgmfile = file(pgmfilename, 'w')
    pgmfile.write('P5\n{} {}\n255\n'.format(w,h))
    # Generate image
    for y in range(h):
        for x in range(w):
            c = centre + complex(((x-(w-1)/2.0)*pxw),(((h-1)/2.0-y)*pxw))
            z = 0
            n = 0
            while abs(z) < limit and n < 51:
                    z = (pow(z,a) + c)/(pow(z,b) - c)
                    n = n + 1
                except ZeroDivisionError:
                    z = limit
            row[x] = int(255 * (0.5 + 0.5*math.cos(math.pi*n/51.0)))
    # Close file
    subprocess.call('mogrify -format png ' + pgmfilename, shell=True)
    subprocess.call('rm ' + pgmfilename, shell=True)

I used a second Python script to rename the PNG frames as frame001.png, frame002.png, etc.

# renamer.py - Written by Ted Burke, last updated 12-1-2016

import subprocess

# Create fractal image files
for t in range(401):
    b = t/100.0
    origfilename = 'crpf_a5.000_b{:1.3f}_pxw0.010_lim4.0_800x400px.png'.format(b)
    newfilename = 'frame{:03d}.png'.format(t)
    print(origfilename + ' ' + newfilename)
    subprocess.call('cp ' + origfilename + ' ' + newfilename, shell=True)

Finally, I used ffmpeg to combine the individual PNG frames into a single video file, as follows:

ffmpeg -framerate 10 -i frame%03d.png -c:v libx264 -pix_fmt yuv420p out.mp4
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s