I played with a similar approach a while ago. By changing the algorithm a bit it's possible to create various other beautiful images:<p><a href="https://drive.google.com/drive/folders/1TSgLRdO0tKIFUb6Oj8yNJgUeh2D_WA9-?usp=sharing" rel="nofollow">https://drive.google.com/drive/folders/1TSgLRdO0tKIFUb6Oj8yN...</a><p>Here's a link to my post (unfortunately, in Russian) describing the process: <a href="https://t.me/little_pieces/822?single" rel="nofollow">https://t.me/little_pieces/822?single</a><p>A quick translation:<p>1. We have a 2D space and a regular shape with N angles, where N is a parameter.<p>2. Choose a function f : R -> R (e.g. f(x) = x / 2 for Sierpinsky).<p>3. Choose a random "current" point<p>4. Choose a random angular point of the N-shape<p>5. Calculate the distance D between two points. Move the current point to the selected angle point by distance calculated as f(D).<p>6. Repeat steps 4-5, saving position of the current point on each step, until there is enough data to draw a density map<p>Another person from gen-club[0] (Russian telegram chat dedicated to generative art) made a 3D-version of it[1][2]:<p>[0] <a href="https://t.me/gen_c" rel="nofollow">https://t.me/gen_c</a><p>[1] <a href="https://t.me/mathimages/156" rel="nofollow">https://t.me/mathimages/156</a><p>[2] <a href="https://codepen.io/strangerintheq/full/ZEKXamr" rel="nofollow">https://codepen.io/strangerintheq/full/ZEKXamr</a> (zoom out at startup)
Here's a quick proof as to how it works. Suppose the triangle has endpoints (0,0), (1,0), and (1/2, sqrt(3)/2). Given a point (x,y), the three transformations then become<p>f1(x,y) = (x/2, y/2)<p>f2(x,y) = (x/2+1/2, y/2)<p>f3(x,y) = (x/2 + 1/4, y/2 + sqrt(3)/4)<p>which are precisely the maps in the Iterated Function System [1] which generate the Sierpinsky triangle!<p>It's a very nice observation that the three maps have a concise representation in terms of taking the midpoint with the given point and the vertices of the triangle.<p>[1] <a href="https://en.wikipedia.org/wiki/Iterated_function_system" rel="nofollow">https://en.wikipedia.org/wiki/Iterated_function_system</a>
"Pick a random vertex of the triangle and find its midpoint with p" is actually "Take the whole triangle, and scale it down to half size, and place it so that it shares a random vertex". This is the basic structure of the Sierpinski triangle, so repeating this process creates the fractal shape of the Sierpinski.
I think this is basically the "chaos game."<p><a href="https://en.wikipedia.org/wiki/Chaos_game" rel="nofollow">https://en.wikipedia.org/wiki/Chaos_game</a>
I believe this is also the algorithm included in the TI-83 (plus) manual: <a href="https://www.manualowl.com/m/Texas%20Instruments/TI-83-Plus/Manual/240607?page=573" rel="nofollow">https://www.manualowl.com/m/Texas%20Instruments/TI-83-Plus/M...</a><p>I remember sitting on the floor of our living room programming this in character by character on that TI keyboard. It's the first BASIC program I ever wrote. Everything before that was js and html.
I thought I'd note that one of my favorite pages on the web pertains to exploring Sierpinski triangles [0]<p>"The sierpinski triangle page to end most sierpinski triangle pages ™"<p>[0]:<a href="http://www.oftenpaper.net/sierpinski.htm" rel="nofollow">http://www.oftenpaper.net/sierpinski.htm</a>
The method presented by the author is the only method I've ever known. It was both simple enough for me to understand as a kid, and fast enough that I could plot the results within a minute using HiSoft BASIC on my Amiga 500.<p>Just to add the curiosum, the method as it was explained to me as a kid: "Plot a pixel on any corner of the triangle. Pick a new corner on random and plot a pixel halfway between there and where your last pixel was, then just repeat."
As others have pointed out, a generalization of this method (iterated function systems) can generate a large class of fractals. There's a some fun software for generating these ( see <a href="https://en.wikipedia.org/wiki/Fractal_flame" rel="nofollow">https://en.wikipedia.org/wiki/Fractal_flame</a>) which also adds coloring based on the sequence of function applications, resulting in a pattern that respects the fractal structure.<p>Going a step further, changing the "functions" over time can create smoothly animated fractals. Electric Sheep (<a href="https://electricsheep.org/" rel="nofollow">https://electricsheep.org/</a>) is a screensaver version of this which doubles as a distributed computing network to generate them. It also mixes in non-linear transformations which makes for some impressive, mesmerizing patterns.
You’ll find some more insight from Numberphile here, <a href="https://youtu.be/kbKtFN71Lfs" rel="nofollow">https://youtu.be/kbKtFN71Lfs</a>
The chaos game is one of my favorite things! I first came across it nearly 15 years ago from James Gleick's excellent book Chaos and in fact I learned how to program so that I could actually implement the chaos game.<p>After spending many years idly reflecting on why the chaos game converged to the Sierpinski triangle, I'd like to share an illustrated proof of mine that might be enjoyed by this audience: <a href="https://arun.chagantys.org/technical/2020/04/28/chaos-game.html" rel="nofollow">https://arun.chagantys.org/technical/2020/04/28/chaos-game.h...</a>
Here is a version which can be played by up to three persons sharing a keyboard:<p><a href="https://www.speicherleck.de/iblech/stuff/chaosspiel-2015/chaosspiel.html" rel="nofollow">https://www.speicherleck.de/iblech/stuff/chaosspiel-2015/cha...</a><p>Developed as part of a mathematics day for children, the worksheet is available here: <a href="https://www.speicherleck.de/iblech/stuff/chaosspiel-2015/arbeitsblaetter.pdf" rel="nofollow">https://www.speicherleck.de/iblech/stuff/chaosspiel-2015/arb...</a>
This is how I learned to draw the Sierpinsky triangle, I don't even know the analytical method. I got this method from fractint[0] I think, it had great docs explaining some of the fractal types. This was sometime in the mid 90's.<p>[0] <a href="https://en.wikipedia.org/wiki/Fractint" rel="nofollow">https://en.wikipedia.org/wiki/Fractint</a><p>EDIT: Also, as a bonus this method is very easy to do with a pen and paper. I remember trying that, but it takes a lot of points before the structure starts to become visible.
This is what got me into programming... I had fiddled with Print "My Name Is Bob" in an infinite loop, and decided that there was nothing interesting programming could do...<p>Then a relative wrote this algorithm in about 10 lines of qbasic. I was amazed that such simple code could do something so complex and unexpected. As a 5 yr old child, I spent hours trying to figure out how on earth this algorithm worked - even though it's blatantly obvious to adult me.
Kudos to whoever included it in the TI82's manual, it successfully tickled my curiosity when I was a kid in the 90s and played a part in me becoming a programmer.<p><a href="https://www.manualslib.com/manual/325928/Ti-Ti-82.html?page=202#manual" rel="nofollow">https://www.manualslib.com/manual/325928/Ti-Ti-82.html?page=...</a>
It's funny, so each point is only guaranteed to be in that iteration of the triangle. So if you want a sierpinski triangle accurate to n levels deep you want to throw away the first n-1 points. If you want to plot a specific sierpinski triangle you have to re-run the algorithm from the beginning to get more points.
This isn't new. I first learned about Sierpinski triangles with this algortihm in the early 90s. Later, I learned how it can be generalised to IFS and opened my eyes to much more interesting examples. I think there's even an entire chapter on this specific algorithm in Barnsley's Fractals Everywhere book.
I remember there being a section demonstrating this in the manual for my TI-83 calculator [0]<p>It prompted me to learn a bit more about IFS and discover one of my favorite fractals ever. The word "chaos" where each stroke is made up of the word "chaos" [1]. I spent a bunch of time coding up the fractals on that site [2] on my calculator<p>[0] <a href="http://manualsdump.com/en/manuals/texas_instruments-ti-83/132084/573" rel="nofollow">http://manualsdump.com/en/manuals/texas_instruments-ti-83/13...</a><p>[1] <a href="http://paulbourke.net/fractals/ifs/chaos_1.gif" rel="nofollow">http://paulbourke.net/fractals/ifs/chaos_1.gif</a><p>[2] <a href="http://paulbourke.net/fractals/ifs/" rel="nofollow">http://paulbourke.net/fractals/ifs/</a>
You can make it using Cellular Automata too.<p>Python Code:<a href="https://nbviewer.org/github/Nydhal/Python-Notebooks/blob/master/Selmi_Impossible_Fractal.ipynb" rel="nofollow">https://nbviewer.org/github/Nydhal/Python-Notebooks/blob/mas...</a>
Cool.
Shameless plug:<p>Sierpinski carpet L-system<p>677 bytes will render a Sierpinski carpet using an L-system to create a Z-order curve :<p><a href="https://github.com/jankovicsandras/misc" rel="nofollow">https://github.com/jankovicsandras/misc</a>
The Sierpinski triangle was the first "complex" system I had managed to draw, using the Logo programming language in the 90s. I recently tried to do a vtk 3D extension (Sierpinski cube)[1] using the same process as in the OP, but it was surprisingly computationally expensive!<p>[1] <a href="https://en.wikipedia.org/wiki/Menger_sponge" rel="nofollow">https://en.wikipedia.org/wiki/Menger_sponge</a>
Love comp prob & geom ;) Coolest part is the algo to generate uniform random points bounded within any triangle. I feel like its useful in loads of applications: FEM, monte carlo rendering, etc.<p><a href="https://blogs.sas.com/content/iml/2020/10/19/random-points-in-triangle.html" rel="nofollow">https://blogs.sas.com/content/iml/2020/10/19/random-points-i...</a>
I did the same thing, but in Python, some years ago [1]. Never understood how it works, but it's easy to implement..<p>[1] <a href="https://joaoventura.net/blog/2016/sierpinski-triangle/" rel="nofollow">https://joaoventura.net/blog/2016/sierpinski-triangle/</a>
Also rule 90 tends to generate them from the nil seed - try clicking on the banner I made and set window size to something even and the seed to zero.<p><a href="https://rileystew.art/posts/banner" rel="nofollow">https://rileystew.art/posts/banner</a>
Here's a version of the same as a BBC Microbot tweet
<a href="https://twitter.com/bbcmicrobot/status/1333542986588753921" rel="nofollow">https://twitter.com/bbcmicrobot/status/1333542986588753921</a>
Why it works:<p>Imagine what would be required to put a dot in an area that ought to be blank... The previous point would have had to have been outside the triangle, or in another blank area at the previous step.<p>Hence, it is impossible to draw in the blank areas.
Could you write a function so that for point (x,y) it returns true if the point is "in" the spierpinski triangle? Yes, I am wondering if it could be expressed as a fragment shader :)