Text in Chaotica

Text in Chaotica

After pressing the ‘new random worlds’ button in Chaotica a few too many times I thought would be time to bring some order to playing the chaos game. Chaotica offers a low barrier to entry for creating perplexingly stunning fractals. There’s no need to exactly understand how it all exactly works. Stephen Wolfram believes the way to get children excited for science is to first spark their interest in a topic by having them play with the end result first and then hit them with the theory. On that note: here’s an implementation you can directly play around with!


A B C D E F P
Post affine

The implementation above was written in Javascript and is quite limited in what it can do in terms of shading (none). If you're interested in the more advanced Chaotica: here's a GitHub repository that contains a Python script that converts IFS to Chaotica parameters for you to explore. Try to understand how the code works or play around with parameters in the world editor to see what they do. If you're not interested I have saved you a lengthy scroll downwards. If you are then I'm happy to explain how this works. Chaotica is available for free (with some minor limitations) on Linux, Mac and Windows and can be downloaded here. The article assumes you have a basic knowledge of Chaotica (the manual is quite comprehensive).

Iterated function systems

Chaotica uses something called an Iterated Function System (IFS). The Wikipedia I have linked here is quite useless if you're not familiar with mathematical notation. I would often give up understanding something when all searches ended up in needlessly complicated explanation, so will keep it simple and start with an example.

    \[F_0(x,y)=(\frac{x}{2},\frac{y}{2})\]

    \[F_1(x,y)=(\frac{x+1}{2}, \frac{y}{2})\]

    \[F_2(x,y)=(\frac{x}{2},\frac{y+1}{2})\]

To play the chaos game you need functions, a pen, graphing paper, and a die. For this particular example, I will use the functions above this paragraph. These three functions each take Cartesian XY coordinates as input and output new Cartesian XY coordinates. Feel free to experiment with a different set of functions, but note that each function must take and return a set of Cartesian XY coordinates. Now follow these steps:

  1. Draw a large square on your graphing paper
  2. Blindfold yourself, you can use duct tape if you don't have a blindfold
  3. Take your pen and place a dot within the square drawn in step 1. This may take multiple attempts. Take your time
  4. The dot from step 3 is your initial Cartesian XY coordinates. The square is a so-called bi-unit square. The bottom-left has coordinates (0,0), top-right (1,1) and the middle (0.5, 0.5)
  5. Roll your die and observe the outcome
  6. If you rolled a one or a two pick function F_0. Pick F_1 if you rolled a three or a four, and F_2 otherwise
  7. If this your first time at step 7 input the coordinates from step 4 into the function picked at step 6, otherwise input the coordinates that resulted from the last time you visited this step. Note down the output from this step
  8. Place a dot at the coordinates you noted down in step 7 and go back to step 5, unless you are bored, then you are allowed to stop

Congratulations! You just played the chaos game. If everything went right, you will have ended up with something like the image below: the Sierpiński gasket. If you didn't, don't worry, computers don't fudge numbers and they love repetitive stuff and they love repetitive stuff.

Sierpinski Gasket

The particularly astute may have noticed that the first few dots don't exactly align with the Sierpiński gasket. In the paper 'The Fractal Flame Algorithm' by Draves et al. the pseudocode for the algorithm skips plotting the first 20 iterations. This would likely dissuade people from trying so I left it out.

Many fractals on this page use a set of affine transformations and have an accompanying table of values.

    \[F_n(x,y)=(ax + by + e, cx + dy + f)\]

abcdefp
F_00.00.00.00.160.00.00.01
F_10.2-0.260.230.220.01.60.07
F_2-0.150.280.260.240.00.440.07
F_30.850.04-0.040.850.01.60.85

Instead of equiprobable odds of choosing a function, this particular flame fractal has a p that indicates the probability that the function is chosen from the set. Translating this to Chaotica gives us the famed Barnsley Fern. Note that this render looks slimmer than the render of the Wikipedia page, because the Wikipedia canvas is scaled. This brings me to another topic. The curious might have tried entering the values from the table above in the small renderer I wrote. Only a few dots likely showed up. That's because this transforms from the table apply to a different scale and translation. By translating and scaling during the render step the fractal should show up as it's supposed to. These are called post-transforms and can be seen as transforms applied to the entire fractal. Try feeding the last row beneath the renderer the following values: 0.09, 0, 0, 0.09, 0.5 and 0.9 respectively. There is no p, because this transformation is always applied!

Barnsley Fern

Chaotica

How do we translate an IFS to Chaotica? Let's first dissect what an affine transformation does. An affine transformation scales, translates and rotates vectors. In this particular case, we're interested in manipulating 2D-vectors or pixel coordinates. We've seen these operations in the tables above. Chaotica also uses these types of operations.

To see what an operation does calculate the outcome operation applied on the vectors of the unit square ([0,0], [0,1], [1,0], [1,1]). Chaotica uses lengths angles and offsets which you can calculate using the original unit squares with the transformed vectors. I advise you to draw these and brush up on your high school geometry homework.

For each function in the system add a new iterator in the world editor. For each iterator add a new transform. The new transform will automatically be a linear transformation, exactly what we need. Now in the flam3 transform dropdown select 'pre affine'. Here you can change the scale, translation, and rotation. Now change the weights to reflect the probabilities from the table. The base weight can remain unchanged.

If you did things right you will see a fractal render on the main screen. But the astute will notice that the fractal seems inverted and upside down. For some inexplicable reason Chaotica the Y-axis angle is the angle between the original angle and the vector [0,1] + 90 degrees. To make it easy I have made a Python script that will do all these operations for you.

The inverse problem

The title of this blog wasn't clickbait. I will now show you how to do the inverse, i.e. find the functions that lead to the desired flame fractal (text in this case). There are in my opinion two tractable ways of doing it: the hard way at your expense or the hard way at a computer's expense. There is no easy way. The former is just manual trial and error by translating, rotating, and scaling affine transform functions with some intelligent guesses, and the latter automated trial and error in the form of an evolutionary algorithm.

Although it is hard to find functions for your specific text, it doesn't mean you need to reinvent the wheel. Learning from examples and then modifying them is a much easier way. A quick Google search leads you to the excellent IFS page of Paul Bourke that contains the functions to create the 'Chaos' fractal flame (it also has the weights for the Barnsley Fern).

One important clue is the number of segments. The word CHAOS has 19 segments in total when written in a font like the one you'll find on a digital clock. To start you off, find out how many segments you need, and then fill each row in the p column with the reciprocal of the number you find (e.g. 1/19 for the word chaos). Try finding which segment belongs to which and perhaps remove the C or S. Removing the begin or end letter reveals that each segment is scaled so that it exactly fits the segment. I recommend finding segments similar to the ones you need and then in- or decrease a value and see what it does. Use this technique to position your segments as you please. Once you have found your text fractal you can apply all sorts of operations to them, like below.

(2022 edit) Here's a Turtletoy I coded

This blog is a work in progress. Hope you enjoyed it nevertheless! If something is unclear or if you have some critique please let me know at matigekunstintelligentie@gmail.com