Excessively Adequate

UJI – Creating Generative Art With a Parametric, Iterative Line-Drawing Routine

This (now long) past summer, deeply interested in generative art and finding myself scrolling through the #plottertwitter hashtag most days, I set off to build a kind of generator I hadn’t yet come across: a simple, web-based tool that first generates a line and then iteratively applies an exhaustive set of parameterized (so, user-controllable!) transformations to it, drawing the line after each iteration.

Meet UJI.

UJI’s interface, photoshopped onto a stock photo of a laptop more recent than mine.

In this post, I’ll briefly outline the thoughts behind UJI’s interface design, explain the core algorithm at a relatively high level (take a look at the code for details), and finally show off a diverse bunch of drawings I’ve created with UJI since its initial release.

Interface

UJI’s interface, as you can see above, is deliberately minimalist. It’s intended to recede into the background, empowering the user to focus on creating art through play.

The drawing area, where the image is automatically redrawn each time one of the parameters is modified, takes up the bulk of the viewport – if larger than the available pixels, it’s automatically resized to fit. There’s a sidebar filled with controls:

If a user has previously visited UJI, a small popup will appear near the undo button on load, offering to restore the parameter values from the most recent session – to make this possible, they’re continuously written to localStorage within the user’s browser. (UJI has no server component; it’s a single HTML file.)

Algorithm

Despite the complex behaviors commonly emergent during the drawing process, the algorithm at the core of UJI could barely be more straightforward:

After generating the initial line based on the parameters related to shape, size, position, and rotation angle, during each iteration a bit of math is applied to it depending on the values of various parameters and the iteration number. As part of this iterative cycle, the line is repeatedly painted onto a canvas given the parameters relating to color and blend modes.

This process starts anew each time the user modifies a parameter (or loads a preset, which really just modifies multiple parameters).

I’ll explain things in more detail below – to help you dive deeper into implementation details, if you wish to do so, the green links point directly to the relevant code snippets.

Line generation

There’s four basic shapes – a circle, a square, a triangle, and a line – whose initial size, position, and rotation angle can be adjusted by the user. How many line segments the shape will be composed of is also a parameter; small values of this parameter can produce interesting artifacts (and are generally more suited for pen plotting). Based on this information, UJI generates a list of x and y coordinates, two adjacent pairs of which define a line segment.

There’s some trigonometry involved in generating a circle (see “parametric form” here), and a bit of logic in generating a square (to arrange the first quarter of line segments in a horizontal line, then the next quarter in a connected vertical line, and so on) and triangle (fairly similar), and barely anything in generating a basic line. To make things easier, the initial rotation parameter is applied after the shape has been generated.

Another parameter processed during this stage is the one I call “line swappiness”, where a certain number of entries in the list of coordinate pairs are swapped, which can yield intriguing effects in a finished drawing.

As part of this initial setup step, the canvas is also prepared for drawing: If required, it’s resized to match the selected image dimensions, its previous contents are erased, and the background is drawn, optionally with a parametric amount of noise – I find that this makes the resulting drawings look less flat. Also, the parameters for line colors, line shadows and blend modes are processed during line generation.

Iterative drawing

In an asynchronous loop that runs 60 times a second, the line is first drawn and then modified according to the parameters and some basic math that I arrived at through trial and error more than, say, rigorous physically-based rendering theory.

In every iteration, the following actions are performed for each line segment:

There’s a user-defined limit to the number of iterations carried out, after which the final drawing can be downloaded. The interface remains active while the image is drawn, any changes will restart the drawing process from the beginning.


Nothing too tricky, right?

I arrived at this set of transformations incrementally – adding the ones that initially came to mind, then playing a bit, thinking of more, rinse and repeat. That’s also why the order of operations is perhaps a little unintuitive - UJI grew organically, the resulting dependencies between different parameters, in my mind, add to the charm of the tool and its proclivity to generate interesting stuff.

Coming up with a good end result is all about discovering a promising family of parameter values that combine in interesting and unforeseen ways through play and then refining them, homing in on a specific set of values that produce an attractive drawing. Some knowledge of the algorithm certainly helps during this latter stage, the dissemination of which has really been the impetus for writing this post.

Having spent many hours making art with UJI during its development and regularly returning to it since, I’ve ended up with a handful of pieces that I’m really happy with. What’s more, I frequently discover combinations of parameters that yield new families of unexpected and wildly different-from-anything-I’ve-done-so-far results, so I’m confident that what’s below isn’t the best stuff that can possibly be made with UJI – so give it a spin and make your own art!

Clicking on any of the images below takes you to the corresponding UJI share link where you can play with the parameters for that drawing.