Click on the animation to view full size gif.
This is the code I used to generate the animation:
// // fraktalismus modulo - written by Ted Burke 15-1-2019 // Compiled and tested on Xubuntu Linux 18.10 // // To compile: // gcc -o fraktalismus fraktalismus.c -lm // // To run: // ./fraktalismus // // To create mp4 video from frames using ffmpeg: // ffmpeg -f image2 -framerate 15 -i "%04d.png" output.gif // #include <stdio.h> #include <stdlib.h> #include <math.h> #include <complex.h> int main() { // Declare variables unsigned char *p; // buffer of rgb pixels for each frame complex double *q; // stores a frame of complex pixel values double qmagn, qarg; // magnitude and angle of unsigned char r, g, b; // colour components of each pixel int w=4*1366, h=4*768; // image width and height int n, x, y, t, T; // t is the frame number int xoffset, yoffset; // shifts centre point of image in complex plane complex double z, c, coffset; // z is the iterated complex value double zmax; // z values wrap around at this magnitude double px; // width/height of each pixel in complex plane FILE *fimage; // file pointer for writing pnm files char pnm_filename[256]; // stores PNM image filename for each frame char png_filename[256]; // stores PNG image filename for each frame char command[1024]; // buffer for imagemagick shell command // Allocate memory for pixels p = malloc(w*h*3); q = malloc(w*h*sizeof(complex double)); // Generate frames of the animation one by one T = 31; for (t=0 ; t<T ; ++t) { // Generate pixel values c = -0.6 -0.725*I + 0.025*cexp(I*2.0*t*M_PI/T); xoffset = -600*4; yoffset = -500*4; px = 0.0007/4.0; zmax = 1000.0; for (y=0 ; y<h ; ++y) for (x=0 ; x<w ; ++x) { // Iterate complex function z = px * ((x-w/2.0+xoffset) + I*(y-h/2.0+yoffset)); coffset = 0.025 * cexp(I*atan2(y,x)); for (n=0 ; n<10 ; ++n) { z = z*z + c + coffset; if (cabs(z) > zmax) { z = fmod(cabs(z), zmax) * cexp(I*carg(z)); } } // Find end point of this point's N-step orbit q[y*w + x] = z; } for (y=0 ; y<h ; ++y) for (x=0 ; x<w ; ++x) { // Set RGB components of current pixel qmagn = log(cabs(q[y*w + x])); qarg = carg(q[y*w + x]); r = 255.0 * qmagn * 0.5 * (1.0 + cos(qarg + 0*2.0*M_PI/3.0)); g = 255.0 * qmagn * 0.5 * (1.0 + cos(qarg + 1*2.0*M_PI/3.0)); b = 255.0 * qmagn * 0.5 * (1.0 + cos(qarg + 2*2.0*M_PI/3.0)); r = 255 - r; g = 255 - g; b = 255 - b; p[3*(y*w + x) + 0] = r; p[3*(y*w + x) + 1] = g; p[3*(y*w + x) + 2] = b; } // Write image to PNM file sprintf(pnm_filename, "%04d.pnm", t); sprintf(png_filename, "%04d.png", t); fprintf(stderr, "Writing %s\n", pnm_filename); fimage = fopen(pnm_filename, "w"); fprintf(fimage, "P6\n%d %d\n255\n", w, h); fwrite(p, 3, w*h, fimage); fclose(fimage); // Convert image to PNG format and then delete PNM file sprintf(command, "convert %s -resize 25%% %s", pnm_filename, png_filename); fprintf(stderr, "Executing: %s\n", command); system(command); sprintf(command, "rm %s", pnm_filename); fprintf(stderr, "Executing: %s\n", command); system(command); } // Free dynamically allocated memory free(p); free(q); }
The version below is obtained by modifying the iterating function on line 59 of the program, as follows:
z = (z*z + c + coffset)/(z*z - c + coffset);
Click on the animation to view full size version.