In this short post, I'll explain how I made the two pieces called Unexpected Loops:
and
It all started with me wanting to somehow simulate the taffy mixing machines (or the process of creating noodles with hand) in a shader (GLSL). I came up with this special transformation (stretch, slice, rotate, combine) because I could animate it in a satisfying way:
But putting the fancy animation aside, this is what each step of the transformation does (considering the transformation acts on a square of size 2 with it's center sitting at (0,0) ):
The next thing I needed was the inverse transformation function which could easily be found. At last I could create the animation: Animation(position , time), using this method:So I drew an initial pattern (using parametric rectangles in GLSL) and then using a method like this, the final animation was like the latter (red-yellow) gif you see above. It was nice, I got what I wanted and the noodles were ready! But as you may be familiar with my work, I'm always looking for the loops!
Creating loops is really my passion! I love them from the viewpoint of a physicist. I always ask is it possible for a physical world to be periodic and repetitive? Of course not, the second law of thermodynamic and the concept of the arrow of time highly forbid that (The initial and final state of a universe should differ in the value of entropy). the mixed can never be unmixed. So I always love to take the challenge of unmixing the mixed, at least in my gif simulations.
For example this post from Matt Henderson(@matthen2) made me really excited some months ago:
(A double pendulum with special initial conditions, showing periodic behavior, which is something unthinkable for this kind of chaotic systems)
So considering this mixing transformation as the time evolution of a system, could we set the initial condition somehow for it to repeat after a few steps? The answer is yes.
Part 1: The Green GIF
First I implemented both f(x,y) and it's inverse in shader code. Take a simple pattern (the ✕ in the green animation for example) calling it "Pattern A", Then consider (from now on I change my notation of passive/active transformations, but you'll get the idea):
Then let's add these two patterns in an additive way (literally adding the color of pixels):
Now consider Pattern C as our initial pattern, what happens if we go 5 steps into the future?
The final state is not the same as the initial state (+5 instead of -5), but after watching the resulted animation I noticed that:
(Which I suppose could be explained for this special transformation for every power of f() easily) So now we have a pattern, which after 5 steps plus a π/2 rotation, repeats (The initial "Pattern A" also needs to be symmetric under π/2 rotation for this to hold). This was how the green gif was made! You can see that it folds 5 times and rotates π/2 in each period.
Part 2: The Black and White GIF
As for the black/white gif, I wanted to go a step further and get rid of that π/2 rotation. I just wanted a perpetual cycle to repeat under this transformation.
Consider this notation: black is -1 , grey is 0 and white is +1. Let the background be grey and let's work with these two patterns ⚫ and ⚪ (black and white circles) as our building blocks. Consider this special pattern:
This formula contains every positive and negative power of f. You can easily check that:
Meaning that after each 2 time steps, the pattern repeats! This is what we were looking for! But how should we implement this infinite series? Does this series even has a fine limit in mathematical sense? Well from the mixing property of our transformation, we know that every initial pattern, after sufficient amount of time steps will scatter evenly on the plane ( I know this from experiment!). So for large enough N we have:
And since we considered ⚫ + ⚪ = 0 = Grey, so in the large power sector of the series we kinda expect that the the black and white terms cancel out each other (both positive and negative powers). So we can get the desired result by only finite amount of terms. I kept 10 terms with positive power, and 10 with negative power, Because 2^10 = 1000 and that was the size of the render screen (in pixels).
At last I should mention that in order to reduce the noise in the final result you have to do a high amount of sampling for each pixel (I used more than 100 samples per pixel)
That was all for now. Thank you for reading! Goodbye.
Comments
Post a Comment