Genuary 2024

January 01, 2024

I challenged myself to complete all the prompts for Genuary 2024 (Generative Art January). It was an interesting experience; I learned a lot of new techniques, and came away with some ideas for further exploration. I hope to come back to this post and add source code for some of the interesting ones once I have a chance to clean it up and work out a few kinks.

Each day is given a prompt for writing some code to generate an image or animation. Except where otherwise noted, these images were generated using Python code, typically drawing a vector image either directly to an SVG file or to a Cairo surface. The fractal images operate on raw numpy arrays which are converted to images using Pillow. Read more about Genuary here.

Jan. 1 - Particles

With "Particles", I immediately thought of Brownian Motion. This image traces Brownian Motion of several sets of particles. Each particle within a same-colored set follows the same overall motion, but with slight randomness added for the string-like effect. Even the background is made of Brownian motion of many particles at a much shorter step size.

Jan. 2 - No Palettes

To me, no palettes meant black-and-white only, so this was a study of texture using exclusively black lines. All the same width, but varying lengths and orientations.

Jan. 3 - Droste Effect

Self-similarity in this line fractal, where the overall shape is repeated along each segment of the line, draws similarities to the Droste effect. I wrote a lot of line-fractal code about a year ago, but didn't really finish it by applying styling and other features to make the images easier to generate. This prompt gave me a start in that direction.

Jan. 4 - Pixels

There's not much to say about this one. It's just a grid of pixels following a radial gradient with a bit of random color variation.

Jan. 5 - In the style of Vera Molnár

This is an extension of Day 2, with multiple squares having different textures and densities. I had tried a number of variations while working out the Day 2 square, then realized if put in a grid they look similar to the Vera Molnár grids of squares.

Jan. 6 - Screensaver

This animation was recycled from an animation I made last summer using vector fields. The field remains fixed, but the initial coordinates (the circle) is moving through the field from left to right, while the view window follows it to keep the circle centered. I don't know how well it would actually save a screen, but that doesn't matter.


Jan. 7 - Progress indicator

I haven't done a lot of animations, but the ones I have done, including Day 6 above, were made by taking a bunch of still images and stitching them together using ffmpeg.


Jan. 8 - Chaotic System

For my "Chaotic System", I pulled out one of my classic orbit trap fractals. This is one of my first fractals really considered "art", rather than just playing with code.

Jan. 9 - ASCII

Can you find the hidden message? I actually coded up one of these "single image random text stereogram" generators way back in the 90s when these things were everywhere (remember Magic Eye books?) and I was just getting started with coding. I think it used Visual Basic 6. That code being long lost, I quickly put it back together in Python to make this one. To see the 3D effect, focus your eyes behind the screen, as if you're looking at your reflection instead of the screen.

The code is pretty simple. Each row starts with a random sequence of 10 characters, repeated across the width of the image. To go up in depth, add another character to the repeated sequence. To go down in depth, remove a character from the sequence.

Click here for the raw text

Jan. 10 - Hexagonal

I dusted off my Truchet Tiling code and updated it to arrange the hexagonal tiles in a large hexagon grid with specific edge and corner tiles. I still want to experiment with some more complex shapes inside the tiles.

UPDATE: Code is available on github.

Jan. 11 - In the style of Anni Albers

For me, this one was really another study in use of SVG filters to apply the textured-paper effect. Read more about Anni Albers and her style.

Jan. 12 - Lava lamp

This is an adaptation of one of my orbit trap fractals that always gives me the impression of flowing paint or lava lamp bubbles. Can you find the original in my gallery?

Jan. 13 - Wobbly Function Day

This traces the points on a circle through a wobbly field, fading colors along the way. The same technique I describe in my post on vector fields.

Jan. 14 - Less than 1KB artwork

I write a lot of code for programatically generating SVG images (schemdraw is a great example). But I haven't done a whole lot with SVG filters. So I thought I'd try making a filter-based SVG image and keep it to less than 1 kilobyte. The first try ended up around 1050 bytes, but then was able to shrink it down to 978 bytes by removing extra whitespace and shrinking ID names.

Note this is a PNG rendering of the image, as the original is rendered with slight differences in different browsers or viewers. Click here to see the original SVG and it's source.

Jan. 15 - Use a physics library

For this one, I decided to give Pymynk a try. Here it's simulating the path of three double pendulums with different lengths. The color within each path corresponds to the velocity at that point.

Jan. 16 - Draw 10000 of something

This pattern is made from 10000 circles, whose position, diameter, and color are all defined by parametric equations. More examples of this style are in my Line Art gallery.

Jan. 17 - Inspired by Islamic art

I wouldn't call this one finished, but I got some code laid out to create Girih tiles. It needs a bit of styling, and some fancier code to position the tiles so they're not just manually hard-coded. This is one I want to revisit later.

Jan. 18 - Bauhaus

This is an extension of my previous Genuary days that combines tiling with SVG textures, in a Bauhaus style.

Jan. 19 - Flocking

"Flocking", but not in the bird sense.

Jan. 20 - Generative typography

For typography, I used my Python library Ziafont, which I wrote to read font files and convert the glyphs to SVG paths. It was developed to support Ziamath for light-weight typesetting of mathematical expressions in pure Python. But for Genuary, instead of drawing the Bézier curves that normally outline a glyph, it takes the Bézier control points and randomly connects them with line segments. Generated from the QTAbbie font.

Jan. 21 - Use a library you haven't used before

Believe it or not, I've never used the Processing library, so I tried it out and generated this image of flow through a Perlin noise field. It does seem nice, but I probably won't adopt it regularly simply because I've already built up my own library of similar graphics functions over the years, and that's what I'm used to using now. I guess I like doing things the hard way.

Jan. 22 - Point-Line-Plane

Demonstrating textures made from simple drawing primitives, here's a circle made of points, another made of lines, and one made of planes (triangles).

Jan. 23 - 64x64

Genuary played a trick on us and gave everyone different dimensions, from 8x8 to 128x128. I got 64x64. Instead of a 64-pixel image, I made a grid of 64 x 64 circles.

Jan. 24 - Impossible Objects

Short on time today, so I recycled an older fractal image that maybe sort of fits the theme?

Jan. 25 - Recreate a photo/texture

My house has these Mexican Talavera tiles along a half-wall that we really like. My overly-ambitious idea was to recreate my favorite tiles using basic generative shapes and equations in code, but I only had time to do one tile, so here it is.

This photo shows the real tiles, along with a 23-pound (10.5 kg) cat "for scale".

Jan. 26 - Grow a seed

Perhaps I took this one too literally, but it was a fun branching algorithm.


Jan. 27 - Code for an hour

I spent an hour playing with Perlin Noise. Each color is based on the same noise field but with higher octaves added.

Jan. 28 - Skeuomorphism

How about a fractal made to look like a flower?

Jan. 29 - Signed Distance Functions

After reading up on signed distance functions, I realized it's the same technique as rendering a fractal using orbit traps. Color is based on the signed distance to the trap edge, but it's the distance after each pixel goes through the fractal equation. Since most of the SDF references out there use shaders, I created a shader-animated Mandelbrot using a horizontal and vertical orbit trap with the trap position moving back and forth.

Live version is here, source is fully included in the html (just "view source" to see how it works). Video recording below.


Jan. 30 - Shaders

Builing on my first ever attempt at programming shaders from yesterday's post, I used a WebGL shader to animate one of my orbit trap fractal images. It's a single trap moving back and forth. So many example/demo sites hide things away in their own libraries, which made it a bit difficult to learn the basics, but I eventually got it down to a minimal example in this live self-contained demo. Just "view source" to see how it works.

Live version is here Video recording below.


Jan. 31 - Generative audio

The final day of Genuary is "Generative Audio". Instead of trying to generate an audio clip, I used an audio clip to generate an image. Many different clips within a recording of Beethoven's Pathetique Sonata was passed through an FFT with smoothing and coloring applied.