Hi everyone! Long time no post :) Recently, I’ve started going through my copy of Nature of Code again, and working through, well, not everything, but some bits. One of the first things the book talks about is random walkers and random walkers controlled by probabilities. So, I dove into p5.js, trying to relearn javascript while doing something hopefully interesting.

(the structure of this post: I will write up stuff, link to a bl.ocks javascript animation and post screenshots. There is a github link at the end of the post where all the code will live. All the js links are completely randomized and might require a few refreshes to get pleasing color combinations)

So, what about a line-based random walker - something with a grid-like background maybe, with lines of fixed width, that will always create squares if it loops in on itself. My first attempt went well, but I made one crucial mistake in calculating the lengths of diagonals. Still, the results were pretty cool:

Screenshots:

Well, at least that error was easily found and fixed. Despite really liking the results, I went ahead towards what I was actually aiming to make. The “grid based” random walker ended up being interesting but… not enough:

“grid-based” random walker

Screenshots:

Maybe making multiple walkers and giving them highly-saturated, mostly-transparent colors will make for an interesting result? As it turns out, yes, yes it will. The end result of this was something that reminded me of city metro line maps and Mini-Metro.

Metro lines

Screenshots:

Aaaaand… I thought I was done. I was done, right? Start with a simple idea, pursue it a bit and whee pretty results. I had something that was nice to look at, produced pretty images, and seemed… done. At least, I thought so. marienna, however, disagreed.

- “Why can’t you make the area fill up, as the lines start forming triangles?” - “well, um, it’s not what I had in mind when I started this” - “You’re wrong. You should make it with triangles that fill with color”

I did not really intend to go back to it, but she was right, there was more to do with this - the grid was inelegant and required stupid, unnecessary calculations, and if I switched to actually having a proper grid that stored colors of lines that passed through, it would make filling the area much easier.

So, what was wrong with the previous versions? If you look at the first example, the problem is obvious there - instead of actually having a proper grid, I only had line lengths and was “randomly” (ish) selecting angles, using polar transformations to calculate where the next line segment will end.

To make this better, I instead opted to have a grid, an actual 2-dimensional array that stored colors for each grid point. Calculating the new endpoint of the line segment is then as simple as rounding the cos() and sin() of the selected angle, which gives an integer in the [-1, 1] range, then adding those to the current grid position, only multiplying by the side of the grid square after that.

This… might have gotten confusing. To make this obvious to myself and to make completely sure that all calculations were correct, I made a few intermediary versions. The first one was to make sure everything works well with the grid:

Visible grid

Screenshot:

Afterwards, I needed to make sure that the colors were stored correctly inside the grid. The “bubble train” effect was pretty nice:

Bubbles!

Screenshot:

Ok. DONE. All the prep was there, it was time to fill out the triangles. Again, marienna and I did not completely agree. She wanted the fully-opaque, hypnotic, chaotic, version:

Triangles! Chaos!

Screenshots:

The hypnotic chaos that causes my eyes to unfocus and start seeing the triangles in 3d was nice, but if you know anything about me, you know I’m all about the soft pastels. Going back to something like 20% opacity for the colors produced something that made me extremely happy:

Pastel joy

Screenshots:

And, while I was sure I was done after the mini-metro-like, now I am pretty certain that there’s a lot more work to do here. Some of the things I am thinking about/planning:

- instead of just randomly(ish) selecting an angle, actually apply random forces to the walkers, then normalize and snap to grid. This will allow me to later maybe calculate line density at points in the grid, and make points with high densities act as repulsors, or somesuch

- find a good set/several good sets of colors that work well together instead of randomizing them every time.

- make it possible to add arbitrary border lines that will force the walkers back. Make the walkers “push through” these borders for short periods of time, in order to create a more central structure, with more elaborate branching on the outside.

Finally, if this was interesting and you want to see the code, you can find it on github.