An offcut from the Fraktalismus pattern factory

This animation, which I created by accident while trying to do something else, struck me as eye catching.

This is the complete C code used to generate video frames as individual PNM image files:

//
// offcut.c
// Written by Ted Burke, 1-2-2018
// See http://batchloaf.com
//
// To build:
//     gcc -O3 -Wall -o offcut offcut.c -lm
//
// To run:
//     ./offcut 0 1 400
//
// To combine individual frames into a movie:
//     
//     ffmpeg -framerate 8 -f image2 -s 1920x1080 -i %03d.pnm -framerate 8 -s 1920x1080 -i %03d.pnm -filter_complex "[0:v:0][1:v:0]concat=n=2:v=1[outv];[outv]scale=1920x1080[outv]" -c:v libx264 -preset slow -crf 17 -pix_fmt yuv420p -c:a copy -map [outv] -r 8 offcut.mkv
//

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <complex.h>

#define W 3840
#define H 2160

unsigned char p[H][W][3] = {0};

int main(int argc, char **argv)
{
    int n, N=25, x, y, v, t, t_start, t_step, T;
    complex double z, c;
    double zlim = 10.0;
    char filename[1024];
    FILE *f;
    
    t_start = atoi(argv[1]);
    t_step = atoi(argv[2]);
    T = atoi(argv[3]);
    fprintf(stderr, "t_start:%d t_step:%d T:%d\n", t_start, t_step, T);
    
    for (t=t_start ; t<T ; t+=t_step)
    {
        // Vary parameter
        c = -0.825 -0.1*I - 0.2*cexp(I*t*2.0*M_PI/T);
        
        // Generate pixels
        for (y=0 ; y<H ; ++y) for (x=0 ; x<W ; ++x)
        {
            z = 0.002 * (I*(x-W/2.0) + (y-H/2.0));
            
            // This iterating function makes a good texture - it's unusual!
            for (n=0 ; n<N && cabs(z)<zlim ; ++n) z = 1 / (cpow(z,z+c) + c);
            
            // Colour mapping from angle of final z value to shade of blue
            v = 128.0 + 127.0 * carg(z)/M_PI;
            p[y][x][0] = v>127 ? 2*(v-127) : 0;
            p[y][x][1] = v>127 ? 2*(v-127) : 0;
            p[y][x][2] = v>127 ? 255 : 2*v;
        }
        
        // Write current frame to a PNM image file
        sprintf(filename, "%03d.pnm", t);
        fprintf(stderr, "Writing file %s...", filename);
        f = fopen(filename, "w");
        fprintf(f, "P6\n%d %d\n255\n", W, H);
        fwrite(p, 3, W*H, f);
        fclose(f);
        fprintf(stderr, "done\n");
    }
    
    return 0;
}

I decided to render the frames at double resolution (3840 x 2160 px) and then scale back down to 1080p resolution during the video conversion. This was the ffmpeg command I used to combine PNM images into a single video at 8 frames per second, with the full sequence repeated twice:

ffmpeg -framerate 8 -f image2 -s 1920x1080 -i %03d.pnm -framerate 8 -s 1920x1080 -i %03d.pnm -filter_complex "[0:v:0][1:v:0]concat=n=2:v=1[outv];[outv]scale=1920x1080[outv]" -c:v libx264 -preset slow -crf 17 -pix_fmt yuv420p -c:a copy -map [outv] -r 8 mugz.mkv
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a comment