Clusters and Particle Life

This is another great example of emergence. Complex behavior results from many individual particles following simple rules.

Jeffrey Ventrella explains his Clusters here.

Here is another particle based life model

I learned about Clusters when Code Parade posted the following video explaining his version of Clusters he calls Particle Life.

The source code to Particle Life was generously shared here so I had a go at converting the code and playing with these myself.

Results

Here are some of my results.

Extension Into 3D

Once I had the 2D version working, extending into 3D was the next step. These movie parts use the same settings as in the 2D movie above.

Availability

Both the 2D and 3D Particle Life are now included with Visions of Chaos.

Jason.

Extended Neighborhood 1D Cellular Automata

Extended Neighborhood Cellular Automaton

When I first saw this type of cellular automata described by Gugubo on Reddit I was sure I must have implemented it and included it in Visions of Chaos before, but a quick check showed it wasn’t a CA I had covered. There is enough info in the Reddit thread for me to code it up and put it into Visions of Chaos.

Extended Neighborhood Cellular Automaton

This is a 1D Cellular Automaton that uses 5 cells from the previous generation (2 either side and the central cell) to update the new cell state. The larger neighborhood with 2 cells either side is why I called these “Extended Neighborhood” in Visions of Chaos.

Extended Neighborhood Cellular Automaton

There are 4,294,967,296 (2^32) possible “rules” or types in this CA. Each of the rule numbers can be converted into a 32 digit binary number. For example, rule 260 becomes;
00000000000000000000000100000100

Extended Neighborhood Cellular Automaton

To update a cell, use the following steps;
1. Convert the previous step’s left 2 cells, current cell, and right 2 cells into a binary value.
i.e LLCRR may have states 11010 which can be converted into decimal 26
2. Counting from right to left on the binary representation of the rule above, the 26th digit is a 0, so the new cell state is a 0.

Extended Neighborhood Cellular Automaton

The process is repeated for all cells and then repeated for all rows as long as the CA runs.

Extended Neighborhood Cellular Automaton

I also added the option for more than 2 states (alive or dead) per cell. This way, when a cell dies it does not turn instantly into a dead cell, but has a delayed dying period. If there are 4 states per cell then a living cell (state 1) that dies will first go to state 2, then state 3, then finally die (state 0). Only newly born state 1 cells are used in the rule. All other non state 1 cells are considered state 0 when updating the cell based on the binary string rule.

Extended Neighborhood Cellular Automaton

Jason.

3D Multiphase Smoothed-Particle Hydrodynamics

I have wanted to implement a 3D version of a fluid simulation in Visions of Chaos for years (3D was a planned feature since I first got 2D SPH working back in 2013). It took a lot longer than expected.

For the 3D code I extended the 2D SPH code I had into the third dimension. In the end it wasn’t too difficult (everything seems simple once you work out how to do it). After a week or so of hacking away I had multiphase fluids flowing in 3D space.

The code is based on Tom Madam’s SPH Code in this blog post. For 3D you just need to add in a Z dimension for particle positions etc.

3D is slower than 2D with the extra dimension and even with a decent multi-core CPU the simulation starts to crawl as the particle count increases. Using the awesome Mitsuba to render some nicely lit spheres got me the following movie.

Jason.

Hybrid Fractals

Hybrid fractals occur when you alternate between fractal formulas during the inside iteration loop of generating a fractal. The idea came from posts on the old Fractal Forums site.

For example, rather than the usual Mandelbrot Fractal iteration, you can modify the inside loop to alternate between the Mandelbrot, then the Burning Ship, then the Mandelbrot, and the Mandelbrot again. You then repeat the sequence for as many iterations as that pixel needs.

This gives a result like the following

The code to create this (and other hybrid formulas) is included with Visions of Chaos, but you can also see the OpenGL shader code for it here.

I have also used the same hybrid technique for 3D Mandelbulb Fractals as shown here.

Jason.

3D Gravity Simulations and OpenCL

It has been a few years since I last was experimenting with OpenCL for gravity simulations.

At that time I made some mistakes with my code that resulted in not all of the objects being compared to all of the objects in the gravity calculations. For the purists this is not acceptable “How can you call it a gravity simulation if you are not using all objects in the calculations?!” The other opinion raised at the time was if it looks good enough, use the speed ups. None of the comments to my YouTube gravity videos were (in typical YouTube speak) “haha lol! looks fake! u no do gud gravity!”. So, if you are struggling with getting gravity working fast, try reducing the number of actual particle interactions.

Here is the latest updated CL kernel code….


__kernel void Gravity3DKernel(__global float4* pos, __global float4* vel, __global float4* acc, __global float4* mass, float mingravdist, float forcescalefactor, int startindex, int stopindex, int gridsize)
{
	int index=get_global_id(0)+startindex;
	float dx,dy,dz,distance,force;
	float positionx=pos[index].x;
	float positiony=pos[index].y;
	float positionz=pos[index].z;
	acc[index].x=0;
	acc[index].y=0;
	acc[index].z=0;
	for(int a=0; a<get_local_size(0); a++) {
		if (a!=index) {
				
			dx=pos[a].x-positionx;
			dy=pos[a].y-positiony;
			dz=pos[a].z-positionz;
				
			distance=sqrt(dx*dx+dy*dy+dz*dz);
			
			dx=dx/distance;
			dy=dy/distance;
			dz=dz/distance;
				
			force=1/(distance*distance+mingravdist*mingravdist)*forcescalefactor;
				
			acc[index].x+=dx*force;
			acc[index].y+=dy*force;
			acc[index].z+=dz*force;
		}
	}
	vel[index].x+=acc[index].x;
	vel[index].y+=acc[index].y;
	vel[index].z+=acc[index].z;
}


The kernel processes all of the 3d objects once using 1 of the other objects (passed as startindex).

You can call the kernel multiple times each frame/step of the simulation. If you want strictly accurate (and slow) gravity simulation results you call it inside a loop that sets startindex from 1 to the number of objects. In my experiments this is not necessary. If you want “good enough” nice looking gravity simulations then calling the kernel with as little as 10 different startindexes (use a set of objects spread out among all of them or just use a random set of 10 objects each frame).

Here is a recent 4K resolution example movie. This one used 1,000 objects out of 5,000,000 objects for the gravity calculations. The objects start by being randomly placed within an oblate spheroid. Their velocities are initialized so they are rotating around the center axis.

Jason.

Multiple Rules Cellular Automata

Another new CA to experiment with.

The idea for these came from a comment Tsui Kagura left on one of my YouTube videos.

Can you make a CA that is 4D ( or 5D etc ) in a sense, that you use 2 (or more) different regular CA rules, run them in the same space (same coordinates), same time (same steps), but then, based on some kind of rule also have them interact with each other?As if they were neighborhoods from another dimension. I assume we could only be ‘seeing’ one of them, the rest would be in a hidden dimension, but affecting the one we’re looking at. If there are more than one hidden dimensions, they could affect each other too, maybe using a different rule between them…

Using multiple rules on the same CA is something I have not experimented with before, so I had to give it a go.

To start off I used the simplest 2 state 2D CAs. The extension from a usual 2D CA is simple enough. You run 2 rules over the same grid. Store the results of each rule (either 0 or 1 for dead or alive) and then you use the results of the rules to set the new cell state.

How the 2 rule results are converted into a new cell state is the tricky part.

For two 2D CA rules there are 4 possible outcomes (dead dead, dead alive, alive dead, alive alive). So depending on the result states I have 4 options for alive or dead. This gives the following options.

Multiple Rules Cellular Automaton

Here are a few sample results after trying hundreds of random rules.

Multiple Rules Cellular Automaton

Multiple Rules Cellular Automaton

Multiple Rules Cellular Automaton

Multiple Rules Cellular Automaton

I will update this post if I find any more interesting results. There are many more extensions to try like 3D, 4D, 5D, larger neighborhoods, more than 2 rules, etc.

I did try the 3D version of multiple rules. Nothing worth posting as yet. I used both the result1 and result2 method above and also tried feeding the result of rule1 into rule2. Neither has given any unique looking results yet.

Jason.

Searching for pleasing looking Flame Fractals

Flame Fractal

Flame Fractals were originally developed by Scott Draves as an extended version of Iterated Function Systems.

Flame Fractal

See this PDF for a more thorough explanation.

Flame Fractal

Visions of Chaos has supported flames for years now, but something I recently revisited was detecting interesting looking flame fractals.

Flame Fractal Settings Dialog

The flame fractals appearance are controlled by the coefficients, probabilities, transformations and multiplier values (the lower table floating point values in the above dialog), but 99% of the time if you just set random values it will lead to boring images. Boring here means an image that is just a few straight lines, a circle, or only a few pixels.

Searching for an interesting flame fractal means repeatedly randomizing the controlling parameters and testing the resulting plotted points. Here is a snippet of code I use to test each random set of parameters.


     xp:=0.05;
     yp:=0.05;
     //skip first 1000 iterations to allow it to settle down
     for loop:=1 to 1000 do iterate_point; 
    
     repeat
           thisxp:=xp;
           thisyp:=yp;

           //iterate the next point
           iterate_point;

           //test if tending to a point
           if (abs(thisxp-xp)<1e-10) and (abs(thisyp-yp)<1e-10) then
           begin
                TestFlameParameters:=false;
                exit;
           end;

           //check if unbounded, ie values are getting too large
           if (abs(xp)>10000) or (abs(yp)>10000) then
           begin
                TestFlameParameters:=false;
                exit;
           end;

           //check for NAN
           if (isnan(xp)) or (isnan(yp)) then
           begin
                TestFlameParameters:=false;
                exit;
           end;

           //check for INF
           if (isinfinite(xp)) or (isinfinite(yp)) then
           begin
                TestFlameParameters:=false;
                exit;
           end;

           //count pixels that fall within the image area
           if (xp<xmax) then
           if (xp>xmin) then
           if (yp<ymax) then
           if (yp>ymin) then
           begin
                xplot:=trunc((xp-xmin)/abs(xmin-xmax)*width);
                yplot:=trunc((yp-ymin)/abs(ymin-ymax)*height);
                hitpixelscount[xplot,yplot]:=hitpixelscount[xplot,yplot]+1;
           end;

           inc(pointcount);

     until (pointcount=250000);

     //count pixels hit
     hits:=0;
     for y:=0 to height-1 do
         for x:=0 to width-1 do
             if hitpixelscount[x,y]>5 then inc(hits);
     if hits<trunc(width*1.5+height*1.5) then
     begin
          TestFlameParameters:=false;
          exit;
     end;
     //if it got to here then the tests all passed

The tests included in the code and the ones I found most useful are;

1. Detect tending to a single point. A lot of flames result in the iterations being attracted to a single point/pixel.
2. Unbounded. Points continue to grow outwards to infinity.
3. NAN and INF. If the floating point math returns a NAN or INF.
4. Count pixels hit. If the resulting image has too few pixels the flame picture will be boring. Counting the pixels helps detect and avoid these flames.

Using those 4 checks will skip hundreds (at least in my case) of parameters that fail one or more of the above tests. The result is when looking for new random flame fractals you skip the boring point-like and line-like displays.

The following screen shot of the flame mutator in Visions of Chaos shows a series of flames that all passed the tests. They may not all be interesting aesthetically, but there are no minimal results with just a small number of pixels.

Flame Fractal Mutator Dialog

I did also experiment with lyapunov values, ie
http://technocosm.org/chaos/attr-part2.html
http://sprott.physics.wisc.edu/software.htm
but in my tests they are too unreliable to detect good vs boring flames.

Flame Fractal

If you know of any other reliable ways to detect good vs bad/boring flame fractals, let me know by email or reply to this post.

Flame Fractal

Jason.