2D Strange Attractors

Strange Attractors are plots of relatively simple formulas. They are created by repeating (or iterating) a formula over and over again and using the results at each iteration to plot a point. The result of each iteration is fed back into the equation. After millions of points have been plotted fractal structures appear. The repeated points fall within a basin of attraction (they are attracted to the points that make up these shapes).

I recently revisited my old strange attractor code in Visions of Chaos to add some new variations. This post will show many of the strange attractor formulas and some 4K resolution sample images they create. The images were created using over 1 billion points each. They have also been oversampled at least 3×3 pixels to reduce aliasing artifacts.

Bedhead Attractor

Discovered by Ivan Emrich.


x and y both start at 1.0

xnew=sin(x*y/b)*y+cos(a*x-y)
ynew=x+sin(y)/b

Variables a and b are floating point values bewteen -1 and +1

Bedhead Attractor

A=0.65343 B=0.7345345

Bedhead Attractor

A=-0.81 B=-0.92

Bedhead Attractor

A=-0.64 B=0.76

Bedhead Attractor

A=0.06 B=0.98

Bedhead Attractor

A=-0.67 B=0.83

Clifford Attractor

Discovered by Clifford A Pickover. I found them explained on Paul Bourke‘s page here.


x and y both start at 0.1

xnew=sin(a*y)+c*cos(a*x)
ynew=sin(b*x)+d*cos(b*y)

Variables a,b,c and d are floating point values bewteen -3 and +3

Clifford Attractor

A=-1.7 B=1.3 C=-0.1 D=-1.21

Clifford Attractor

A=-1.7 B=1.8 C=-0.9 D=-0.4

Clifford Attractor

A=1.5 B=-1.8 C=1.6 D=2

Clifford Attractor

A=-2.239 B=-2.956 C=1.272 D=1.419

Clifford Attractor

A=-1.7 B=1.8 C=-1.9 D=-0.4

Fractal Dream Attractor

Discovered by Clifford A Pickover and discussed in his book “Chaos In Wonderland”.


x and y both start at 0.1

xnew=sin(y*b)+c*sin(x*b)
ynew=sin(x*a)+d*sin(y*a)

Variables a and b are floating point values bewteen -3 and +3
Variables c and d are floating point values between -0.5 and +1.5

Fractal Dream Attractor

A=-0.966918 B=2.879879 C=0.765145 D=0.744728

Fractal Dream Attractor

A=-2.9585 B=-2.2965 C=-2.8829 D=-0.1622

Fractal Dream Attractor

A=-2.8276 B=1.2813 C=1.9655 D=0.597

Fractal Dream Attractor

A=-1.1554 B=-2.3419 C=-1.9799 D=2.1828

Fractal Dream Attractor

A=-1.9956 B=-1.4528 C=-2.6206 D=0.8517

Gumowski-Mira Attractor

The Gumowski-Mira equation was developed in 1980 at CERN by I. Gumowski and C. Mira to calculate the trajectories of sub-atomic particles. It can also be used to create attractor images.


x and y both start at any floating point value between -20 and +20

t=x
xnew=b*y+w
w=a*x+(1-a)*2*x*x/(1+x*x)
ynew=w-t

The a and b parameters can be any floating point value between -1 and +1.

Gumowski Mira Attractor

Initial X=0 Initial Y=0.5 A=0.008 B=-0.7

Gumowski Mira Attractor

Initial X=-0.723135391715914 Initial Y=-0.327585775405169 A=0.79253300698474 B=0.345703079365194

Gumowski Mira Attractor

Initial X=-0.312847771216184 Initial Y=-0.710899183526635 A=0.579161538276821 B=-0.820410779677331

Gumowski Mira Attractor

Initial X=-0.325819793157279 Initial Y=0.48573582014069 A=0.062683217227459 B=-0.436713613104075

Gumowski Mira Attractor

Initial X=0.78662442881614 Initial Y=0.919355855789036 A=0.900278024375439 B=0.661233567167073

Hopalong Attractor

The Hopalong attractor was discovered by Barry Martin.


x and y both start at 0

xnew=y-1-sqrt(abs(b*x-1-c))*sign(x-1)
ynew=a-x-1

The parameters a, b and c can be any floating point value between 0 and +10.

Hopalong Attractor

A=7.16878197155893 B=8.43659746693447 C=2.55983412731439

Hopalong Attractor

A=7.7867514709942 B=0.132189802825451 C=8.14610984409228

Hopalong Attractor

A=9.74546888144687 B=1.56320227775723 C=7.86818214459345

Hopalong Attractor

A=9.8724800767377 B=8.66862616268918 C=8.66950439289212

Hopalong Attractor

A=9.7671244922094 B=4.10973468795419 C=3.78332691499963

Jason Rampe 1

A variation I discovered while trying random formula changes.


x and y both start at 0.1

xnew=cos(y*b)+c*sin(x*b)
ynew=cos(x*a)+d*sin(y*a)

Variables a, b, c and d are floating point values between -3 and +3

Jason Rampe 1 Attractor

A=2.6 B=-2.5995 C=-2.9007 D=0.3565

Jason Rampe 1 Attractor

A=1.8285 B=-1.8539 C=0.3816 D=1.9765

Jason Rampe 1 Attractor

A=2.5425 B=2.8358 C=-0.8721 D=2.7044

Jason Rampe 1 Attractor

A=-1.8669 B=1.2768 C=-2.9296 D=-0.4121

Jason Rampe 1 Attractor

A=-2.7918 B=2.1196 C=1.0284 D=0.1384

Jason Rampe 2

Another variation I discovered while trying random formula changes.


x and y both start at 0.1

xnew=cos(y*b)+c*cos(x*b)
ynew=cos(x*a)+d*cos(y*a)

Variables a, b, c and d are floating point values between -3 and +3

Jason Rampe 2 Attractor

A=1.546 B=1.929 C=1.09 D=1.41

Jason Rampe 2 Attractor

A=2.907 B=-1.9472 C=1.2833 D=1.3206

Jason Rampe 2 Attractor

A=0.8875 B=0.7821 C=-2.3262 D=1.5379

Jason Rampe 2 Attractor

A=-2.4121 B=-1.0028 C=-2.2386 D=0.274

Jason Rampe 2 Attractor

A=-2.9581 B=0.927 C=2.7842 D=0.6267

Jason Rampe 3

Yet another variation I discovered while trying random formula changes.


x and y both start at 0.1

xnew=sin(y*b)+c*cos(x*b)
ynew=cos(x*a)+d*sin(y*a)

Variables a, b, c and d are floating point values between -3 and +3

Jason Rampe 3 Attractor

A=2.0246 B=-1.323 C=-2.8151 D=0.2277

Jason Rampe 3 Attractor

A=1.4662 B=-2.3632 C=-0.4167 D=2.4162

Jason Rampe 3 Attractor

A=-2.7564 B=-1.8234 C=2.8514 D=-0.8745

Jason Rampe 3 Attractor

A=-2.218 B=1.4318 C=-0.3346 D=2.4993

Jason Rampe 3 Attractor

A=1.2418 B=-2.4174 C=-0.7112 D=-1.9802

Johnny Svensson Attractor

See here.


x and y both start at 0.1

xnew=d*sin(x*a)-sin(y*b)
ynew=c*cos(x*a)+cos(y*b)

Variables a, b, c and d are floating point values between -3 and +3

Johnny Svensson Attractor

A=1.40 B=1.56 C=1.40 D=-6.56

Johnny Svensson Attractor

A=-2.538 B=1.362 C=1.315 D=0.513

Johnny Svensson Attractor

A=1.913 B=2.796 C=1.468 D=1.01

Johnny Svensson Attractor

A=-2.337 B=-2.337 C=0.533 D=1.378

Johnny Svensson Attractor

A=-2.722 B=2.574 C=1.284 D=1.043

Peter DeJong Attractor

See here.


x and y both start at 0.1

xnew=sin(y*a)-cos(x*b)
ynew=sin(x*c)-cos(y*d)

Variables a, b, c and d are floating point values between -3 and +3

Peter DeJong Attractor

A=0.970 B=-1.899 C=1.381 D=-1.506

Peter DeJong Attractor

A=1.4 B=-2.3 C=2.4 D=-2.1

Peter DeJong Attractor

A=2.01 B=-2.53 C=1.61 D=-0.33

Peter DeJong Attractor

A=-2.7 B=-0.09 C=-0.86 D=-2.2

Peter DeJong Attractor

A=-0.827 B=-1.637 C=1.659 D=-0.943

Peter DeJong Attractor

A=-2 B=-2 C=-1.2 D=2

Peter DeJong Attractor

A=-0.709 B=1.638 C=0.452 D=1.740

Symmetric Icon Attractor

These attractors came from the book “Symmetry in Chaos” by Michael Field and Martin Golubitsky. They give symmetric results to the attractors formed.


x and y both start at 0.01

zzbar=sqr(x)+sqr(y)
p=alpha*zzbar+lambda
zreal=x
zimag=y
for i=1 to degree-2 do
begin
     za=zreal*x-zimag*y
     zb=zimag*x+zreal*y
     zreal=za
     zimag=zb
end
zn=x*zreal-y*zimag
p=p+beta*zn
xnew=p*x+gamma*zreal-omega*y
ynew=p*y-gamma*zimag+omega*x
x=xnew
y=ynew

The Lambda, Alpha, Beta, Gamma, Omega and Degree parameters can be changed to create new plot shapes.

These sample images all come from paramters in the “Symmetry in Chaos” book.

Symmetric Icon - Chaotic Flower

L=-2.5 A=5 B=-1.9 G=1 O=0.188 D=5

Symmetric Icon - Clam Triple

L=1.56 A=-1 B=0.1 G=-0.82 O=0.12 D=3

Symmetric Icon - Emporer's Cloak

L=-1.806 A=1.806 B=0 G=1 O=0 D=5

Symmetric Icon - Fish and Eye

L=-2.195 A=10 B=-12 G=1 O=0 D=3

Symmetric Icon - Flintstone

L=2.5 A=-2.5 B=0 G=0.9 O=0 D=3

Symmetric Icon - French Glass

L=-2.05 A=3 B=-16.79 G=1 O=0 D=9

Symmetric Icon - Halloween

L=-2.7 A=5 B=1.5 G=1.0 O=0 D=6

Symmetric Icon - Kachina Dolls

L=2.409 A=-2.5 B=0 G=0.9 O=0 D=23

Symmetric Icon - Mayan Bracelet

L=-2.08 A=1 B=-0.1 G=0.167 O=0 D=7

Symmetric Icon - Pentacle

L=-2.32 A=2.32 B=0 G=0.75 O=0 D=5

Symmetric Icon - Pentagon

L=2.6 A=-2 B=0 G=-0.5 O=0 D=5

Symmetric Icon - Sanddollar

L=-2.34 A=2 B=0.2 G=0.1 O=0 D=5

Symmetric Icon - Swirling Streamers

L=-1.86 A=2 B=0 G=1 O=0.1 D=4

Symmetric Icon - Trampoline

L=1.56 A=-1 B=0.1 G=-0.82 O=0 D=3

Symmetric Icon - Trinity

L=1.5 A=-1 B=0.1 G=-0.805 O=0 D=3

Symmetric Icon - Untitled 01

L=1.455 A=-1 B=0.03 G=-0.8 O=0 D=3

Symmetric Icon - Unititled 02

L=2.39 A=-2.5 B=-0.1 G=0.9 O=-0.15 D=16

3D Alternatives

Strange Attractors can also be extended into three dimensions. See here and here for my previous experiments with 3D Strange Attractors.

All of the images in this post were created using Visions of Chaos.

Jason.

Fractal Spirographs

Inspiration

Daniel Shiffman has been making YouTube movies for some time now. His videos focus on programming and include coding challenges in which he writes code for a target idea from scratch. If you are a coder I recommend Dan’s videos for entertainment and inspiration.

His latest live stream focused on Fractal Spirographs.

If you prefer to watch a shorter edited version, here it is.

He was inspired by the following image from the Benice Equation blog.

Fractal Spirograph

Fractal Spirographs (aka Fractal Routlette) are generated by tracking a series (or chain) of circles rotating around each other as shown in the above gif animation. You track the chain of 10 or so circles and plot the path the final smallest circle takes. Changing the number of circles, the size ratio between circles, the speed of angle change, and the constant “k” changes the resulting plots and images.

How I Coded It

As I watched Daniel’s video I coded my own version. For my code (Delphi/pascal) I used a dynamic array of records to hold the details of each circle/orbit. This seemed the simplest approach to me for keeping track of a list of the linked circles.

  
type orbit=record
     x,y:double;
     radius:double;
     angle:double;
     speed:double;
end;

Before the main loop you fill the array;

     
//parent orbit
orbits[0].x:=destimage.width/2;
orbits[0].y:=min(destimage.width,destimage.height)/2;
orbits[0].radius:=orbits[0].y/2.5;
orbits[0].angle:=0;
orbits[0].speed:=0;
rsum:=orbits[0].radius;
//children orbits
for loop:=1 to numorbits-1 do
begin
     newr:=orbits[loop-1].radius/orbitsizeratio;
     newx:=orbits[loop-1].x+orbits[loop-1].radius+newr;
     newy:=orbits[loop-1].y;
     orbits[loop].x:=newx;
     orbits[loop].y:=newy;
     orbits[loop].radius:=newr;
     orbits[loop].angle:=orbits[loop-1].angle;
     orbits[loop].speed:=power(k,loop-1)/sqr(k*k);
end;

Then inside the main loop, you update the orbits;


//update orbits
for loop:=1 to numorbits-1 do
begin
     orbits[loop].angle:=orbits[loop].angle+orbits[loop].speed;
     rsum:=orbits[loop-1].radius+orbits[loop].radius;
     orbits[loop].x:=orbits[loop-1].x+rsum*cos(orbits[loop].angle*pi/180);
     orbits[loop].y:=orbits[loop-1].y+rsum*sin(orbits[loop].angle*pi/180);
end;

and then you use the last orbit positions to plot the line, ie


canvas.lineto(round(orbits[numorbits-1].x),round(orbits[numorbits-1].y));

Results

Once the code was working I rendered the following images and movie. They are all 4K resolution to see the details. Click the images to see them full size.

Fractal Spirograph

Fractal Spirograph

Fractal Spirograph

Fractal Spirograph

Fractal Spirograph

Here is a 4K movie showing how these curves are built up.

Fractal Spirographs are now included with the latest version of Visions of Chaos.

Finally, here is an 8K Fulldome 8192×8192 pixel resolution image. Must be seen full size to see the fine detailed plot line.

Fractal Spirograph

To Do

Experiment with more changes in the circle sizes. The original blog post links to another 4 posts here, here, here and here and even this sumo wrestler

Fractal Spirograph

Plenty of inspiration for future enhancements.

I have already experimented with 3D Spirographs in the past, but they are using spheres rotating within other spheres. Plotting the sqheres rotating around the outside of other spheres should give more new unique results.

Jason.

The Belousov-Zhabotinsky Reaction and The Hodgepodge Machine

Inspiration for this post

The other day I saw this YouTube video of a Belousov-Zhabotinsky Cellular Automaton (BZ CA) by John BitSavage

After a while of running in an oscillating state it begins to grow cell like structures. I had never seen this in BZ CAs before. I have seen similar cell like growths in Digital Inkblot CAs and in the Yin Yang Fire CA. Seeing John’s results different to the usual BZ CA was what got me back into researching BZ in more depth.

The Belousov-Zhabotinsky Reaction

Belousov-Zhabotinsky Reactions (see here for more info) are examples of a chemical reactions that can oscillate between two different states and form intetesting patterns when performed in shallow petri dishes.

Here are some sample high res images of real BZ reaction by Stephen Morris. Click for full size.

Belousov-Zhabotinsky Reaction

Belousov-Zhabotinsky Reaction

Belousov-Zhabotinsky Reaction

and some other images from around the Internet

Belousov-Zhabotinsky Reaction

Belousov-Zhabotinsky Reaction

Belousov-Zhabotinsky Reaction

Belousov-Zhabotinsky Reaction

and some sample movies I found on YouTube

The Hodgepodge Machine Cellular Automaton

Back in August 1988, Scientific American‘s Computer Recreations section had an article by A. K. Dewdney named “The hodgepodge machine makes waves”. After a fair bit of hunting around I could not find any copies of the article online so I ended up paying $8 USD to get the issue in PDF format. The PDF is a high quality version of the issue, but $8 is still a rip off.

In the article Dewdney describes the “hodgepodge machine” cellular automaton designed by Martin Gerhardt and Heike Schuster of the University of Bielefeld in West Germany. A copy of their original paper can be seen here.

How the Hodgepodge Machine works

The inidividual cells/pixels in the hodgepodge automaton have n+1 states (between 0 and n). Cells at state 0 are considered “healthy” and cells at the maximum state n are said to be “ill”. All cells with states inbetween 0 and n are “infected” with the larger the state representing the greater level of infection.

Each cycle of the cellular automaton a series of rules are applied to each cell depending on its state.

(a) If the cell is healthy (i.e., in state 0) then its new state is [a/k1] + [b/k2], where a is the number of infected cells among its eight neighbors, b is the number of ill cells among its neighbors, and k1 and k2 are constants. Here “[]” means the integer part of the number enclosed, so that, for example, [7/3] = [2+1/3] = 2.

(b) If the cell is ill (i.e., in state n) then it miraculously becomes healthy (i.e., its state becomes 0).

(c) If the cell is infected (i.e., in a state other than 0 and n) then its new state is [s/(a+b+1)] + g, where a and b are as above, s is the sum of the states of the cell and of its neighbors and g is a constant.

The parameters given for these CA are usual q (for max states), k1 and k2 (the above constants) and g (which is a constant for how quickly the infection tends to spread).

My previous limited history experimenting with BZ

Years ago I implemented BZ CA in Visions of Chaos (I have now correctly renamed the mode Hodgepodge Machine) and got the following result. This resolution used to be considered the norm for YouTube and looked OK on lower resolution screens. How times have changed.

The above run used these parameters
q=200
k1=3
k2=3
g=28

Replicating Gerhardt and Miner’s results

Gerhadt and Miner used fixed values of k1=2 and k2=3. The majority of their experiments used a grid size of q=20 (ie only 20×20 cells) without a wraparound toroidal world. This leaves the single infection spreading g variable to play with. Their paper states they used values of g between 1 and 10, but I get no spirals with g in that range.

Here are a few samples which are 512×512 sized grids with wraparound edges and many thousands of generations to be sure they had finally settled down. Each cell is 2×2 pixels in size so they are 1024×1024 images.

Hodgepodge Machine

q=100, k1=2, k2=3, g=5

Hodgepodge Machine

q=100, k1=2, k2=3, g=20

Hodgepodge Machine

q=100, k1=2, k2=3, g=25

Hodgepodge Machine

q=100, k1=2, k2=3, g=30

Results from other parameters

Hodgepodge Machine

q=100, k1=3, k2=3, g=10

Hodgepodge Machine

q=100, k1=3, k2=3, g=15

Hodgepodge Machine

q=100, k1=3, k2=3, g=20

Extending into 3D

The next logical step was extending it into three dimensions. This blog post from Rudy Rucker shows a 3D BZ CA from Harry Fu back in 2004 for his Master’s degree writing project. I must be a nerd as I whipped up my 3D version over two afternoons. Surprisingly there are no other references to experiments with 3D Hodgepodge that I can find.

The algorithms are almost identical to their 2D counterparts. The Moore neighborhood is extended into three dimensions (so 26 neighbors rather than 8 in the 2D version). It is difficult to see the internal structures as they are hidden from view. Methods I have used to try and see more of the internals are to slice out 1/8th of the cubes and to render only some of the states.

Clicking these sample images will show them in 4K resolution.

3D Hodgepodge Machine

q=100, k1=1, k2=18, g=43 (150x150x150 grid)

3D Hodgepodge Machine

q=100, k1=1, k2=18, g=43 (150x150x150 grid – same as previous with a 1/8th slice out to see the same patterns are extending through the 3D structure)

3D Hodgepodge Machine

q=100, k1=1, k2=18, g=43 (150x150x150 grid – same rules again, but this time with only state 0 to state 50 cells being shown)

3D Hodgepodge Machine

q=100, k1=2, k2=3, g=15 (150x150x150 grid)

3D Hodgepodge Machine

q=100, k1=3, k2=6, g=31 (150x150x150 grid)

3D Hodgepodge Machine

q=100, k1=4, k2=6, g=10 (150x150x150 grid)

3D Hodgepodge Machine

q=100, k1=4, k2=6, g=10 (150x150x150 grid – same rules as the previous image – without the 1/8th slice – with only states 70 to 100 visible)

3D Hodgepodge Machine

q=100, k1=3, k2=31, g=43 (250x250x250 sized grid – 15,625,000 total cells)

3D Hodgepodge Machine

q=100, k1=4, k2=12, g=34 (350x350x350 sized grid – 42,875,000 total cells)

3D Hodgepodge Machine

q=100, k1=1, k2=9, g=36 (400x400x400 sized grid – 64,000,000 total cells)

Download Visions of Chaos if you would like to experiment with both 2D and 3D Hodgepodge Machine cellular automata. If you find any interesting rules please let know in the comments or via email.

Mandelbrot Movies Remastered

In the video game industry older games get remastered all the time. Hardware power improves so older games are adapted to have better graphics and sound etc. So for a nostalgic trip into history (at least for me) it was time for some Visions of Chaos movie remasters.

After recently adding the new Custom Formula Editor into Visions of Chaos I decided to go back and re-render some sample Mandelbrot movies at 4K 60fps. Most of these Mandelbrot movie scripts go back to the earliest days of Visions of Chaos even before I first released it on the Internet. The only changes made have been to add more sub frames so they render more smoothly and last longer.

Thanks to the new formula editor using OpenGL shading language and a recent NVidia GPU all the movie parts rendered overnight. Every frame was 2×2 supsampled so the equivalent of rendering an image 4 times as large and then downsampling to increase the quality. The original movie was a 46 GB XVID encoded AVI before YouTube put it through all of its internal recoding steps.

Jason.

Diffusion-Limited Aggregation

Diffusion-limited aggregation creates branched and coral like structures by the process of randomly moving particles that touch and stick to existing stationary particles.

All of the images and movies in this post were created with Visions of Chaos.

Real Life Experiments

If you put an electrodeposition cell into a copper sulfate solution you can get results like the following images.

2D Diffusion-limited Aggregation

DLA is a simple process to simulate in the computer and was one of my first simulations that I ever coded. For the simplest example we can consider a 2D scenario that follows the following rules;

1. Take a grid of pixels and clear all pixels to white.
2. Make the center pixel black.
3. Pick a random edge point on any of the 4 edges.
4. Create a particle at that edge point.
5. Move the particle randomly 1 pixel in any of the 8 directions (N,S,E,W,NE,NW,SE,SW). This is the “diffusion”.
6. If the particle goes off the screen kill it and go to step 4 to create a new particle.
7. If the particle moves next to the center pixel it gets stuck to it and stays there. This is the “aggregation”. A new particle is then started.
Repeat this process as long as necessary (usually until the DLA structure grows enough to touch the edge of the screen).

When I asked some of my “non-nerd” aquaintances what pattern would result from this they all said a random blob like pattern. In reality though the pattern produced is far from a blob and more of a coral like branched dendritic structure. When you think about it for a minute it does make perfect sense. Because the moving particles are all coming from outside the fixed structure they have less of a chance of randomly walking between branches and getting to the inner parts of the DLA structure.

All of the following sample images can be clicked to see them at full 4K resolution.

Here is an image created by using the steps listed above. Starting from a single centered black pixel, random moving pixels are launched from the edge of the screen and randomly move around until they either stick to the existing structure or move off the screen.


2D Diffusion-Limited Aggregation

Start configuration: Single centered black pixel
Random pixels launched from: rectangle surrounding existing structure
Neighbours checked for an existing pixel: N, S, E, W, NE, NW, SE, SW
Particles stick condition: when they move next to a single stuck particle


The change in this next example is that neighbouring pixels are only checked in the N, S, E and W directions. This leads to horizonal and vertical shaped branching.


2D Diffusion-Limited Aggregation

Start configuration: Single centered black pixel
Random pixels launched from: rectangle surrounding existing structure
Neighbours checked for an existing pixel: N, S, E, W
Particles stick condition: when they move next to a single stuck particle


There are many alternate ways to tweak the rules when the DLA simulation is running.

Paul Bourke’s DLA page introduces a “stickiness” probability. For this you select a probability of a particle sticking to the existing DLA structure when it touches it.

Decreasing probability of a particle sticking leads to more clumpy or hairy structures.


2D Diffusion-Limited Aggregation

Start configuration: Single centered black pixel
Random pixels launched from: rectangle surrounding existing structure
Neighbours checked for an existing pixel: N, S, E, W, NE, NW, SE, SW
Particles stick condition: 0.5 chance of sticking when they move next to a single stuck particle


2D Diffusion-Limited Aggregation

Start configuration: Single centered black pixel
Random pixels launched from: rectangle surrounding existing structure
Neighbours checked for an existing pixel: N, S, E, W, NE, NW, SE, SW
Particles stick condition: 0.1 chance of sticking when they move next to a single stuck particle


2D Diffusion-Limited Aggregation

Start configuration: Single centered black pixel
Random pixels launched from: rectangle surrounding existing structure
Neighbours checked for an existing pixel: N, S, E, W, NE, NW, SE, SW
Particles stick condition: 0.01 chance of sticking when they move next to a single stuck particle


Another method is to have a set count of hits before a particle sticks. This gives similar results to using a probability.


2D Diffusion-Limited Aggregation

Start configuration: Single centered black pixel
Random pixels launched from: rectangle surrounding existing structure
Neighbours checked for an existing pixel: N, S, E, W, NE, NW, SE, SW
Particles stick condition: once a moving particle has hit stuck particles 15 times


2D Diffusion-Limited Aggregation

Start configuration: Single centered black pixel
Random pixels launched from: rectangle surrounding existing structure
Neighbours checked for an existing pixel: N, S, E, W, NE, NW, SE, SW
Particles stick condition: once a moving particle has hit stuck particles 30 times


2D Diffusion-Limited Aggregation

Start configuration: Single centered black pixel
Random pixels launched from: rectangle surrounding existing structure
Neighbours checked for an existing pixel: N, S, E, W, NE, NW, SE, SW
Particles stick condition: once a moving particle has hit stuck particles 100 times


2D Diffusion-Limited Aggregation

Start configuration: Single centered black pixel
Random pixels launched from: rectangle surrounding existing structure
Neighbours checked for an existing pixel: N, S, E, W, NE, NW, SE, SW
Particles stick condition: once a moving particle has hit stuck particles 1000 times


Another change to experiment with is having a threshold neighbour count random particles have to have before sticking. For example in this next image all 8 neighbours were checked and only 1 hit was required to stick, but the moving particles needed to have at least 2 fixed neighbour particles before they stuck to the existing structure.

The first 50 hits only need 1 neighbour. This build a small starting structure which all the following hits stick to with 2 or more neighbours.


2D Diffusion-Limited Aggregation

Start configuration: Single centered black pixel
Random pixels launched from: rectangle surrounding existing structure
Neighbours checked for an existing pixel: N, S, E, W, NE, NW, SE, SW
Particles stick condition: once a moving particle has 2 or more stuck neighbours


That gives a more clumpy effect without the extra “hairyness” of just adding more hit counts before sticking.


2D Diffusion-Limited Aggregation

Start configuration: Single centered black pixel
Random pixels launched from: rectangle surrounding existing structure
Neighbours checked for an existing pixel: N, S, E, W, NE, NW, SE, SW
Particles stick condition: once a moving particle has 3 or more stuck neighbours


This seems a happy balance to get thick branches yet not too fuzzy ones.


2D Diffusion-Limited Aggregation

Start configuration: Single centered black pixel
Random pixels launched from: rectangle surrounding existing structure
Neighbours checked for an existing pixel: N, S, E, W, NE, NW, SE, SW
Particles stick condition: once a moving particle has 3 or more stuck neighbours and has hit 3 times


The next two examples launch particles from the middle of the screen with the screen edges set as stationary particles.


2D Diffusion-Limited Aggregation

Start configuration: Edges of screen set to black pixels
Random pixels launched from: middle of the screen
Neighbours checked for an existing pixel: N, S, E, W, NE, NW, SE, SW
Particles stick condition: once a moving particle has 1 or more stuck neighbours


2D Diffusion-Limited Aggregation

Start configuration: Edges of screen set to black pixels
Random pixels launched from: middle of the screen
Neighbours checked for an existing pixel: N, S, E, W, NE, NW, SE, SW
Particles stick condition: once a moving particle has 3 or more stuck neighbours


These next three use a circle as the target area. Particles are launched from the center of the screen.


2D Diffusion-Limited Aggregation

Start configuration: Circle of black pixels
Random pixels launched from: middle of the screen
Neighbours checked for an existing pixel: N, S, E, W, NE, NW, SE, SW
Particles stick condition: once a moving particle has 1 or more stuck neighbours


2D Diffusion-Limited Aggregation

Start configuration: Circle of black pixels
Random pixels launched from: middle of the screen
Neighbours checked for an existing pixel: N, S, E, W, NE, NW, SE, SW
Particles stick condition: once a moving particle has 2 or more stuck neighbours


2D Diffusion-Limited Aggregation

Start configuration: Circle of black pixels
Random pixels launched from: middle of the screen
Neighbours checked for an existing pixel: N, S, E, W, NE, NW, SE, SW
Particles stick condition: once a moving particle has 3 or more stuck neighbours


This next image is a vertical 2D DLA. Particles drop from the top of the screen and attach to existing seed particles along the bottom of the screen. Color of sticking particles uses the color of the particle they stick to.


2D Diffusion-Limited Aggregation
Start configuration: Bottom of screen is fixed particles
Random pixels launched from: top of the screen
Neighbours checked for an existing pixel: S, SE, SW
Particles stick condition: once a moving particle has 1 or more stuck neighbours


Dendron Diffusion-limited Aggregation

Another DLA method is Golan Levin’s Dendron DLA. He kindly provided java source code so I could experiment with Dendron myself. Here are a few sample images.

Dendron Diffusion-Limited Aggregation

Dendron Diffusion-Limited Aggregation

Dendron Diffusion-Limited Aggregation

Dendron Diffusion-Limited Aggregation

Dendron Diffusion-Limited Aggregation

Dendron Diffusion-Limited Aggregation

Hopefully all of the above examples shows the wide variety of 2D DLA possible and the various methods that can produce them. This post was mainly going to be about 3D DLA, but I got carried away trying all the 2D possibilities above.

3D Diffusion-limited Aggregation

DLA can be extended into 3 dimensions. Launch the random particles from a sphere rather than a surroundiong circle. Check for a hit against the 27 possible neighbours for each 3D grid cell.

For these movies I used default software based OpenGL spheres. Nothing fancy. Slow, but still managable with some overnight renders.

In this first sample movie particles stuck once they had 6 neighbours. In the end their are approximately 4 million total spheres making up the DLA structure.

This second example needed 25 hits before a particle stuck and a particle needed 5 neighbours to be considered stuck. This results in a much more dense coral like structure.

A Quick Note About Ambient Occlusion

Ambient occlusion is when areas inside nooks and crannies are shaded darker because light would have more trouble reaching them. Normally to get accurate ambient occlusion you raytrace a hemisphere of rays from the surface point seeing how many objects the rays intersect. The more hits, the darker the shading. This is a slow process. For the previous 3D DLA movies I cheated and used a method of counting how many neighbour particles the current sphere has. The more neighbours the darker the sphere was shaded. This gives a good enough fake AO.

Programming Tip

A speedup some people do not realise is when launching random particles. Use a circle or rectangle just slightly larger than the current DLA structure. No need to start random points far from the structure.

Other Diffusion-limited Aggregation Links

For many years now the ultimate inspiration in DLA for me has been Andy Lomas.

http://www.andylomas.com/aggregationImages.html

His images like this next one are very nice.

Another change Andy uses is to launch the random walker particles in patterns that influence the structure shape as in this next image.

Future Changes

1. More particles. The above 2 movies have between 4 and 5 million particle spheres at the end of the movies. Even more particles would give more natural looking structures like the Andy Lomas examples.

2. Better rendering. Using software (non-GPU) OpenGL works but it is slow. Getting a real ray traced result supporting real ambient occlusion and global illumination would be more impressive.

3. Controlled launching of particles to create different structure shapes other than a growing sphere.

Jason.

Visions of Chaos is now compatible with High DPI displays

High DPI

Mobile phones and tablets have had nice high DPI displays for a long time now. PC screens have started to catch up and 4K monitors are starting to come down in price and will become the standard in the future.

The good thing about higher DPI screens is that there are many more pixels on the same sized screen so text and images are shown much more clearly.

The bad thing is most applications (especially older programs) are not aware of High DPI scaling settings. If an application does not support scaling Windows just “zooms” the application window to a larger size. This leads to blurry text that most people complain about. So you either set the scaling factor to 100% which leads to tiny text or you live with blurry text.

Over the past few weeks I have been working on making Visions of Chaos high DPI aware. The end result is that it will now run happily on all scale settings and higher 4K monitors without the text being too tiny to read or blown up and blurry. The menus and all text within Visions of Chaos will scale according to your Windows settings and remain smooth and crisp to read.

High DPI in Visions of Chaos

Prior to Visions of Chaos being DPI aware Windows would just scale the output window like in a photo editor app. The following shows how the Visions of Chaos window looks at 150% scaling under Windows 10 on a 4K display.

Non DPI aware Visions of Chaos image

This leads to the blurred text and the generated image (set to 480×360 pixels in size) is shown onscreen also stretched and blurred to 725 pixels wide.

Here is the same window using the latest version of Visions of Chaos that is DPI aware. The text fonts are scaled to a larger size so they remain crisp and smooth. The fractal image that has been set to 480×360 pixels is exactly 480×360 monitor pixels.

DPI aware Visions of Chaos image

Windows is still playing catch up with higher resolution DPI support, but it will hopefully get better as 4K monitors become the standard. At least you can be confident that Visions of Chaos will continue to be usable and readable at high DPI settings.

Now I can get back to adding new features to Visions of Chaos.

Jason.

Pendulum Plots

This is a quick post showing an alternative way to display the result of plotting double, triple and quadruple pendulums.

Based on my previous magnetic pendulum simulation and plots I had the idea to try a similar plot style for the double, triple and quadruple pendulums.

If you simulate a pendulum attached to another pendulum in zero gravity without any friction you get a system that runs continuously and creates a plot like the following gif animation.

Double Pendulum Simulation

With 3 pendulums the plot is more complex.

Triple Pendulum Simulation

With 4 it is even more complex.

Quadruple Pendulum Simulation

Another way to visualize this is to plot a 2D image with the X axis being 0 to 360 degrees of the first pendulum and the Y axis being 0 to 360 degrees of the second pendulum. The simulations are run for 5000 steps at each pixel location. Depending on which quadrant of the screen the pendulum is in after the 5000 steps determines the color of the pixel (red, green, blue or yellow). The top left pixel sets the pendulum angles to both 0, runs the simulation for 5000 steps and because the end of the two pendulums is located in the lower left quarter of the screen the pixel is colored green. This process is then repeated for the remaining pixels of the image.

Here is the result for the double pendulum

Double Pendulum

and the triple

Triple Pendulum

and the quadruple

Quadruple Pendulum

The original code was taking 12 minutes for a 320×240 image using the simplest double pendulum code. I am patient, but not that patient. A quick recode into GLSL and the GPU took over the number crunching and now it is rendering 640×480 results in under 2 seconds.

Here is a gif animation of the double pendulum plot with the number of simulation iterations increasing each frame.

Double Pendulum Plot Animation

If you are interested in seeing the GLSL shader source code click here.

The above plotting and shader code is now included with Visions Of Chaos if you just want to experiment without having to do any coding.

Jason.