The basic idea is to make an image that is striped, but where the stripe pattern is not consistent across the entire image. The width of the stripes won’t change, but their direction can change and also they can be offset. The image will be broken into an array of cells, and a stripe pattern assigned to each cell. Randomly assigning stripe direction and offset to each cell produces this kind of image:

This random assignment is not very interesting though. The real fun is in introducing correlations between the directions and offsets of neighboring cells. To do this, I use a cost function. The total cost for the whole image is the sum of a cost for each neighboring pair of cells. If neighboring cells have the same direction and offset, the cost for that pair is zero. The more their direction and offset differ, the more that pair contributes to the total cost.

There are some interesting details in how direction and offset can vary. The set of possible stripe patterns of a cell has a topology that characterizes when one stripe pattern, given by a direction and offset, is close to another stripe pattern. For example, when the direction of a stripe pattern is rotated by 180 degrees, it returns to the original stripe pattern. So the direction of the stripe pattern forms a circle, topologically.

Similarly, the offsets of the stripe pattern form a circle topologically. If the stripes are offset far enough, they just end up back where they started.

Given a circular topology of directions and a circular topology of offsets, the obvious way they would combine would be in a torus topology. But that is not what happens here. As the direction is rotated through 180 degrees, offsets in one direction are transformed to offsets in the opposite direction. The topology of the set of directions and offsets of the stripe patterns for a cell actually has the topology of a Klein bottle!

With this understanding of the choices available for a cell, the cost function can be used to drive a simulated annealing algorithm. This algorithm is driven by a temperature parameter. High temperatures give high costs which imply loose correlations between neighboring cells. Low temperatures give low costs and tighter correlations between neighboring cells. Systems such as these generally exhibit phase transitions, where local correlations extend to global correlations. The image above was generated at a temperature just above the phase transition. At a slightly lower temperature, very much higher correlation is observable:

At a lower temperature yet, the system is nearing uniformity.

Generally the fluctuations near the phase transition have a fractal character, so that is where the most interesting patterns appear.

With these elements in place, we can then toy with the various parameters, e.g. the number of cells and the number of stripes per cell.

Here is a plot of the heat capacity which has a sharp peak indicative of a phase transition: