My latest series, titled inertia, was written in Haskell, where I have built up a sizable library of generative algorithms over the years. Working in Haskell enables me to throw all of these techniques together to achieve a more natural feeling result. I'd like to detail the journey that brought me to inertia and talk about some of the techniques I’ve used in it here.
Rectangular subdivision
Rectangular subdivision is a very simple generative technique. The idea is to cut a rectangle vertically or horizontally to produce two rectangles, then rinse and repeat on the target rectangles a number of times. It's a flexible technique I've used in a ton of works, the first being Cluster Bubbles from 2017 (which combines the technique with circle packing):
In inertia, I'm using a version of rectangular subdivision that tends to keep the rectangles as square as possible by weighting the cut axis by the rectangle's opposite axis length:
subdivide :: Rect -> Generate [Rect] subdivide r@Rect{..} = do ctor <- weighted [(Vertically, rectW), (Horizontally, rectH)] a <- getRandomR (1,3) pure $ subdivideRectWith (ctor a) r
This technique is easy to see in inertia, as it forms the basis for the composition of each image.
Poisson disc sampling
One of the first things I noticed when I started working on generative art is that stippling (filling a space with dots) in the "obvious" way doesn't look natural whatsoever. That's because randomness is unintuitive. When we stipple by hand, there is a natural bias. Poisson disc sampling is one technique used to get closer to that natural feel. It works by creating donut-shaped discs around each generated point and generating new points only within those discs, making sure not to place any point too close to another. I used this technique to achieve a stippled feel in my works growth and wire from 2018:
In inertia, this technique is used in a much subtler way: it's used to space the attractors and repulsors (discussed in the next section) an appropriate distance from one another to avoid too much turbulence within each pattern, which keeps each pattern from becoming a muddy mess.
Physics simulations
In my early searches for "natural" feeling generative work, I decided to explore actual physical simulations in my work. I thought, if this is (an approximation of) the way the world actually works, maybe it will elevate the humanity in my digital work. This is a treasure trove, in my opinion. Wire actually uses this technique by placing a repulsor (repelling orb) between the wires to push them around, but the technique is most obvious in my work Good Night from 2018, and its successor, Edifice, from 2021:
Inertia uses two types of orbs. Once a pattern is generated in each rectangle, attractors and repulsors are spawned in an evenly spaced pattern within the rectangle, then pushed in a random direction for a few iterations to create subtle wave-like variations within those patterns.
Colors sourced from paintings
Mastering color is hard. It's especially hard when you have every RGB color available to you to choose from. I've tried a lot of different techniques for generating and sourcing colors, and the one I've been happiest with is this: make a physical painting, take a photo of it, and sample that (manually) to develop palettes from.
This was first explored in my 2021 series Glim, where I applied these randomly generated palettes to a simple triangular subdivision algorithm:
With inertia, I searched for duotone palettes within one of my paintings that worked well together. Some of these duotone palettes are on display in my 2022 color study:
The colors in the color study tend to work well together because they all come from the same source (the painting).
Non-noise-based flow fields
"Flow fields" refer to a technique wherein a particle is let loose in a vector field, which then follows its current and traces out a path. It is a very popular technique within generative works, but most commonly, a noise algorithm is used to determine the backing vectors. I actually didn't even know how to use noise the first time I used this technique, so I wrote my own algorithm generating a vector field and walking through it, and it gave a unique flavor to the work. Discrete Flow from 2017 is my first incantation of this technique:
I used a newer version of it in some unpublished work recently as well:
In inertia, this technique is used to displace the points in each pattern. There's a backing vector field that shifts each point just enough to make them imperfect, but not enough to completely disrupt the pattern.
Line drawing with convex hulls
The convex hull of a set of points is the shape you’d get if you wrap a rubber band around them. It always forms a convex polygon that contains all of the points in the set.
For this project, I was inspired by the aesthetics of linocut prints. With this type of print, linoleum is carved away from a sheet to create a sort of "stamp" which is covered in ink and pressed into a sheet of paper. One thing that tends to happen with these prints is that lines don't retain perfect straightness, or perfect width. They don't necessarily have a ton of texture associated (like a charcoal drawing or painting would), but the solid patterns themselves have a distinct character to them. In order to achieve this aesthetic, I used a new technique I developed, which uses convex hulls.
The idea is this. For each point in a path, generate a small number of dots in a disc around it. Then, pair up adjacent point sets and take the convex hull of all of their generated points together and fill it. Do this for every pair of adjacent point sets, and you have a jagged line.
I have only used this technique in unpublished/unfinished work. Inertia marks its first usage in published work for me, and I’m quite happy with the result.
Releasing Inertia
Inertia will be available as a hand-selected generative edition of 75 NFTs on Foundation through their new Drops mechanic, on November 17th. Because this algorithm is written completely in Haskell (not Javascript) and uses a ton of sizable algorithms, the series is not a good fit for a fully on-chain, long-form project. Instead, I curated a large set from an initial sample of 10,000 images down to the 75 in the final series. This task itself took about a week - it’s atypical for me to go beyond a dozen or so outputs for a curated series.
Moving Forward
Inertia would not be what it is without using all of these algorithms in subtle ways. I think it's important to lay out that even when things appear simple at first glance, there might be a lot going on under the hood with generative work. For generative artists, I hope this sheds some light on the intricacies that go into the craft, and inspires new directions. For appreciators and collectors of the medium, I hope this inspires you to ask questions about these kinds of intricacies. Generative art, to me, is most interesting because of its nuance. I hope this essay encourages you to dig deeper.