Taking a break from some of my more complicated generative art, here’s a little minimalist coding experiment which generates random pictures of braids. This was inspired both by my past mathematical research in braid groups and more recently by the aesthetic of 10 Print, a book (with several authors) which uses a vintage oneline Commodore 64 program as a jumping off point for a discussion of generative art.
There are four versions of the braid application, built in JavaScript and HTML5 canvas, below. Two versions generate fixed images, and two versions endlessly scroll. Click on the screenshots to view them, and refresh the pages to see the braids regenerate. Below you can grab the source code and read a little about mathematical braids and the code.
Download
The complete code for all of the above examples can be downloaded here: Braids.zip
Greeting Cards Available!
I thought these braid images might make interesting graphics for print, so I generated some high resolution versions and put together some greeting cards that you can order at my new Zazzle store.
About braids
I have a background in mathematics, and one mathematical construction that played a part in my past research is the braid group, one particular example of a more general notion of a group. The braid group is a nice example of the intersection of the mathematical areas of abstract algebra and topology, and it has connections to knot theory.
Without going into great detail: the braid group consists of braid diagrams consisting of n strings which are firmly attached to n points at the top of the diagram and n points at the bottom. These braids can be “multiplied” together by concatenation; that is, one braid is attached at the string ends to the another braid to form a longer braid (which is then shrunk down vertically in half so as to be the same size of the original factor braids).
The braid group is “generated” by a set of simple braids which have a single crossing of strings. Below is a picture of one of these generators, followed by a picture of its “inverse”. Note that if the top braid is attached to its inverse, the strings can become untangled, leaving a picture of unbraided strings. This is analogous to the way a number added to its negative makes zero: zero is the identity when dealing with numbers and addition; the configuration of unbraided strings plays the role of the identity in the braid group.
About the code
To draw a braid, we simply draw row by row. As we draw left to right, we randomly select either a positive or negative crossing, or a single unbraided string. Note that if we select a crossing, this takes care of the next two strings so we should increment ahead by two strings before selecting the next random element.
We have to take some care to color the strings properly. The colors are stored in an array, and every time a crossing is drawn, the colors for those strings are transposed in the array. Incidentally, this is an illustration of how a group (the braids) can act on, or permute, a set (the colors).
As an aesthetic choice, to make the braids feel completely, well, braided we might wish to avoid drawing a crossing immediately followed by its inverse, as shown below, because our eyes can see that these strings can be pulled apart.
An array keeps track of the crossings in the last row, and the code rejects a randomly chosen crossing in the present row if it is canceled by one above, and instead the crossing which creates further entanglement is drawn.
There is an interesting probability issue here: when sweeping through a row, the probability of a crossing being drawn is set by a desired probability constant defined in the code. My examples here use a 2/3 (or 67%) probability, but the very first crossing in a row is given a 50% probability. This helps to avoid the first two strings being twisted up more frequently than the second two strings.
Note that the blue version is made to have slowly changing crossing probabilities as the animation evolves.
Drawing the crossings
The “flat” version above draws the braids in the classical manner as seen in mathematical illustrations: where the strings cross each other, there is a little gap to show the crossing. This is accomplished by simply drawing a little “spacer” in between drawing the strings. The spacer is given the same color as the background and drawn under the top string. It has the same bezier curve shape as the top string, except with a thicker stroke weight. The figure below shows the spacer in a transparent gray for the sake of illustration:
What started out an exercise in minimalism later became more complicated as I decided to add some gradient coloring to suggest depth. At a crossing, a dark linear gradient is applied to the string in the back and a subtle light gradient is applied to the front string (see below). A little trigonometry was required to work out the correct points for the start and end of the gradient.
Further reading
I find the braid groups to be such a great example of abstract mathematics which is accessible to a large audience. If you’re interested in more of this sort of thing, I can recommend a very nice introduction to the related topic of knot theory, by author and mathematician Colin Adams: The Knot Book.
Also be sure to check out 10 Print (the full title is 10 PRINT CHR$(205.5+RND(1)); : GOTO 10) which is available in print or as a PDF download.
Wonderful work, thanks. Great blog overall.
May 25, 2014 @ 12:36 am
Thanks!
May 29, 2014 @ 7:42 pm
Thanks again for your great work.
I have put one of your drawing in my site (link above) if you disagree just email me.
Regards
Salvatore
August 15, 2015 @ 12:05 pm
Looks great! Thanks for the mention.
August 15, 2015 @ 5:30 pm
Hi, what license is this released under?
January 9, 2016 @ 7:30 am
Go ahead and use it for whatever you like. Acknowledgment is appreciated but not required. Have fun.
January 10, 2016 @ 3:16 pm
This is super cool, I’m currently learning how to code and it’s pretty awesome, I really like what you did, I’m leaving a code for something I made, I hope you like it.
setTimer(circlefun, 40);
function circlefun(){
removeAll();
for(var i = getWidth(); i >= 1; i–){
var circle = new Circle(i*2);
var color = Randomizer.nextColor();
circle.setPosition(getWidth()/2, getHeight()/2);
circle.setColor(color);
add(circle);
}
}
November 3, 2016 @ 3:07 pm
Thanks Riley! Sorry it took me so long to respond. As you may have noticed I haven’t been updating the blog regularly. Your code looks interesting, but it seems to use some JavaScript library I am not familiar with.
January 30, 2017 @ 4:20 am
