A zip archive of my complete Fraktalismus folder (containing all the content for the presentation) can be download here:
- Fraktalismus.zip (93.9 MB)
This is the code I used to create the Julia Set fractal zoom animation above:
//
// zoom.c - Julia Set fractal zoom animation
// Written by Ted Burke - last modified 23-7-2016
//
// To compile and run in Linux:
//
// gcc zoom.c -o zoom -lm
// ./zoom
//
// To combine the resulting 100 PNG frames into an mp4 video:
//
// ffmpeg -framerate 10 -i %03d.png zoomin.mp4
// ffmpeg -i zoomin.mp4 -vf reverse zoomout.mp4
// ffmpeg -f concat -i list.txt -c copy zoom.mp4
//
// where list.txt contains this...
//
// file 'zoomin.mp4'
// file 'zoomout.mp4'
// file 'zoomin.mp4'
// file 'zoomout.mp4'
//
#include <stdio.h>
#include <complex.h>
#include <stdlib.h>
#define W 1024
#define H 768
void main()
{
complex float z, c;
int i, y, x, n;
unsigned char pixels[H][W];
float px=0.003;
FILE *f;
char filename[100];
char command[255];
for (i=0 ; i<100 ; ++i)
{
px = 0.95 * px;
for (y=0 ; y<H ; ++y)
{
for (x=0 ; x<W ; ++x)
{
c = -0.625 -0.4*I;
z = px*((x-W/2) - I*(y-H/2));
z = z - (-0.03632573427952118+0.027244300709640887*I);
for (n=0 ; cabs(z)<2 && n<255 ; ++n) z = z*z + c;
pixels[y][x] = n;
}
}
sprintf(filename, "%03d.pgm", i);
f = fopen(filename, "w");
fprintf(f, "P5\n%d %d\n255\n", W, H);
fwrite(pixels, W, H, f);
fclose(f);
sprintf(command, "mogrify -format png %s", filename);
system(command);
sprintf(command, "rm %s", filename);
system(command);
}
}
Pantograph animation is by AlphaZeta, sourced from Wikimedia Commons
This is the complete Python code for the Julia Set Explorer:
#
# explorer.py - Real time orbit viewer for iterative complex functions
# Written by Ted Burke, last updated 21-1-2016
#
from Tkinter import *
import math
import sys
def generate_fractal():
sys.stdout.write('Generating fractal for c = {:.3f} + {:.3f}j...'.format(c.real,c.imag))
sys.stdout.flush()
for y in range(h):
for x in range(w):
z = centre + complex(((x-(w-1)/2.0)*pxw),(((h-1)/2.0-y)*pxw))
n = 0
while abs(z) < limit and n < 51:
try:
z = pow(z,a) + c
n = n + 1
except ZeroDivisionError:
z = limit
pixel = int(255 * (0.5 + 0.5*math.cos(math.pi*n/51.0)))
img.put('#{:02x}{:02x}{:02x}'.format(pixel,pixel,pixel),(x,y))
sys.stdout.write('OK\n')
sys.stdout.flush()
def set_z0(event):
global z0
z0 = complex((event.x - w/2) * pxw, (h/2 - event.y) * pxw)
paint()
def set_c(event):
global c
c = complex((event.x - w/2) * pxw, (h/2 - event.y) * pxw)
generate_fractal()
paint()
def paint():
canv.delete("all")
canv.create_rectangle(0, 0, w, h, fill="white")
canv.create_image((0,0), anchor="nw", image=img, state="normal")
z = z0
x = int(w/2 + z.real/pxw)
y = int(h/2 - z.imag/pxw)
canv.create_oval(x-3,y-3,x+4,y+4,fill="green")
for n in range(100):
p1 = z
for m in range(M+2):
if m<=M:
p2 = pow(z,1.0+((a-1.0)*m)/M)
else:
p2 = p2 + c
x1 = int(w/2 + p1.real / pxw)
y1 = int(h/2 - p1.imag / pxw)
x2 = int(w/2 + p2.real / pxw)
y2 = int(h/2 - p2.imag / pxw)
canv.create_line(x1, y1, x2, y2, fill="blue")
p1 = p2
z = pow(z,a) + c
x = int(w/2 + z.real/pxw)
y = int(h/2 - z.imag/pxw)
canv.create_oval(x-3,y-3,x+4,y+4,fill="red")
if (abs(z) > 10): break
# Create master Tk widget
master = Tk()
master.title('Julia Set Explorer - by Ted Burke - see http://batchloaf.com')
# Dimensions and resolution
w,h = 800,800
centre = 0 + 0j
pxw = 0.005
# Create Tk canvas widget
canv = Canvas(master, width=w, height=h)
canv.pack()
canv.bind("<B1-Motion>", set_z0)
canv.bind("<Button-1>", set_z0)
canv.bind("<Button-2>", set_c)
canv.bind("<Button-3>", set_c) # this is actually the right click
# Iterating function parameters
a = 2.0
c = 0.325 + 0.285j
z0 = 0 + 0j
limit = 10
# Number of steps in plotting each curve within each orbit
M = 40
# Create image object to store Julia Set image
img = PhotoImage(width=w, height=h)
# Generate initial Julia Set image
generate_fractal()
paint()
# Main Tk event loop
mainloop()
The code used to create the Julia Set rotation animation above:
//
// rotating.c - Julia set animation generator
// Written by Ted Burke - last modified 23-7-2016
//
// To compile and run (in Linux):
//
// gcc rotating.c -o rotating -lm
// ./rotating
//
// To convert the resulting PGM files into PNG:
//
// mogrify -format png *.pgm
//
// To combine the PNG frames into an mp4 video:
//
// ffmpeg -i %03d.png rotating.mp4
//
#include <stdio.h>
#include <complex.h>
#include <math.h>
void main()
{
complex double z, c, c0;
int x, y, n, N, w, h;
unsigned char i;
double r, px;
px = 0.0025;
w = 1024;
h = 768;
c0 = -0.625 -0.4*I;
N = 200;
r = 0.1;
FILE *f;
char filename[100];
for (n=0 ; n<N ; ++n)
{
sprintf(filename, "%03d.pgm", n);
f = fopen(filename, "w");
printf("Generating %s\n", filename);
fprintf(f, "P5\n%d %d\n255\n", w, h);
for (y=0 ; y<h ; ++y)
{
for (x=0 ; x<w ; ++x)
{
z = px*(x-w/2) + px*(y-h/2)*I;
c = c0 + r * z * cexp(I*(2*M_PI*n)/N);
i = 0;
while(cabs(z)<2 && ++i<127) z = z*z + c;
fputc(255-2*i, f);
}
}
fclose(f);
}
}
The code used to generate the lifeform fractal animation above:
//
// lifeform.c - Julia Set animation generator
// Written by Ted Burke, last updated 23-7-2016
//
// To compile and run (in Linux):
//
// gcc lifeform.c -o lifeform -lm
// ./lifeform
//
// To combine the resulting PNG frames into an mp4 video:
//
// ffmpeg -i %03d.png lifeform.mp4
//
#include <stdio.h>
#include <math.h>
#include <complex.h>
#include <stdlib.h>
#define W 1024
#define H 768
void main()
{
complex float centre = 0 + 2.4I; // complex value at centre of image
float pxw = 0.0053; // pixel width
float limit = 4.0; // once z reaches this value, iteration ceases
float a, b;
complex float c, z;
int t, x, y, n;
char filename[100];
FILE *f;
// Create a buffer to store a row of pixel values
unsigned char pixels[H][W] = {0};
// Create fractal image files
for (t=0 ; t<100 ; ++t)
{
a = 5.0 + 0.05*cos(M_PI*t/50.0);
b = 2.5 + 0.25*sin(M_PI*t/50.0);
// Generate image
for (y=0 ; y<H ; ++y)
{
for (x=0 ; x<W ; ++x)
{
c = centre + (x-(W-1)/2.0)*pxw + ((H-1)/2.0-y)*pxw*I;
z = 0.001; // Using exactly zero seems to cause star speckles
n = 0;
while (cabs(z) < limit && n < 25)
{
if (cpow(z,b) == c)
{
z = limit;
}
else
{
z = (cpow(z,a) + c)/(cpow(z,b) - c);
n = n + 1;
}
}
pixels[y][x] = (int)(255 * (0.5 - 0.5 * cos(M_PI * n / 25.0)));
}
}
// Write image to file
sprintf(filename, "%03d.pgm", t);
f = fopen(filename, "w");
fprintf(stderr, "%s\n", filename);
fprintf(f, "P5\n%d %d\n255\n", W, H);
fwrite(pixels, W, H, f);
fclose(f);
// Convert PGM file to PNG format
char command[255];
sprintf(command, "mogrify -format png %s", filename);
system(command);
sprintf(command, "rm %s", filename);
system(command);
}
}










