flame

flame is the name i use for my iterated function system (IFS) software. it's primary purpose is to create shape.

The basic idea of IFS is that from a handful of simple functions on the plane (eg a 3x2 matrix, or the complex log function), one can generate a picture. Every set of functions defines a different picture. By continuously varying the parameters, the picture can be animated. The shapes appearing in the pictures are fractals, strange attractors in particular.

My interest in iterated function systems (IFSs) goes back to freshman year when Bill Poirier showed me what he called `recursive pictures'. For a graphics class I explored generalizations of this idea, including higher dimensions.

Several implementations later I gave up on a tree of recursive functions producing geometry, and adopted the randomized IFS algorithm (see below), which gives a stream of points in the plane. Just drawing these points produces a crude fractal image. this is how the interactive flame explorer, the xlock mode, and (more or less) the bomb flame mode work.

I produced my first quality monochrome images by collecting a high-resolution (typically 3000x4500) 2D-histogram of these points, taking its point-wise log, and then filtering down to 1000x1500 (the aspect ratio of 35mm film). Because fractals have such detail and texture, correct filtering is essential. The addition of color (see below) resulted in some nice pictures. These images required about four hours each to generate on a 100Mhz R4000.

That much is easy, the hard part of making an IFS picture is picking the functions! Because I was programming with C, this problem naturally broke into two stages: parameterizing a portion of function-space, then picking the coordinates of the desired functions. [connect to nitrous, explain parameterization] Like most people, I started out with affine functions (3x2 matrices). To produce pictures with greater variety of character, the matrix may be composed with a `variation'. Over many months I developed six variations (libifs.c:109):

linear
none
sinusoidal
component-wise sine
spherical
project around unit circle (1/\\bar{z})
swirl
rotate by radius
horseshoe
rotate by angle (z^2/|z|)
fireworks
polar transform (c_0+c_1\\ln z)
bent
piecewise linear (C^1 discontinuities on axes)
Rather than parameterizing with an integer specifying one of these, a vector in R^7 specifies an linear combination. This has the advantage of being continuous. Thus each function has 6+7=13 parameters.

The above parameterization contains only the tiniest sliver of function space, but already the user is confronted with as many as 75 dials to set in order to specify a picture. Furthermore, the relationship between the parameters (dials) and the picture is entirely non-invertible (as is the nature of complexity). So how can one produce interesting pictures?

I chose brute force: generate many random parameter sets, render them very quickly at low-quality, and save any good ones that appear. It was pretty easy to collect 200 that I liked. To guarantee that the matrices are contractive, their entries are chosen in the biunit cube.

this departs from the traditional creative process by factoring it into spew and filter phases. filtering is easy because it's multiple-choice: you only have to recognize what you want. what makes a good spew? diversity and density. see here.


The next stage was animation: because the parameter space and the mapping from parameters to pictures are continuous, a picture can be put in motion by varying its parameters. Furthermore, any two pictures can serve as end points for interpolation, creating an animation that smothly transforms one into the other. I've made one high-quality animation (written frame by frame to video-disc, facilities provided by NTT-data), and several low-quality MPEGs.

The method of interpolation is important: element-wise interpolation of matrices produces more degenerate matrices (zero determinate) than necessary. Such matrices usually don't produce good pictures since they destroy information. An alternative is to break the 3x2 matrix into a 2x2 matrix, and a translation. Interpret the 2x2 matrix as a pair of complex numbers, and interplate them in log-space, and interplate the translation linearly. This feels like a very natural way to interpolate matrices, does it have a name?

An easy way to produce an animation from a single picture is to rotate it: just compose rotations onto each of its functions. This tends to preserve some nature of a picture while utterly transforming it. Furthermore, the transformation is circular: after rotating 360 degrees, the picture returns to its original state. Combining rotation with other matrix operators (scale, translate, spread eigenvalues, etc) might be a good way to provide interactive control of the high-dimensional parameter space.

For the realtime versions of flame (in xlock and bomb), I wanted the image to change continuously and indefinitely, without ever repeating itself. To accomplish this, the matrix parameters follow follow a Lissajous figure in the biunit cube. Each matrix entry is assigned its own random frequency, then the frequencies are collectively normalized to bound the speed of the path in parameter space. The variation-combination parameters remain fixed.

Currently I am working on a After Effects plug-in for flame animation.