I really enjoyed Hunar’s video about a simple particle simulation[1] and wanted to follow their tutorial to recreate it.
I store the parameters in the url so that you can share the url with the current set of parameters, like this example[2] or this example[3].
Thoughts about Hunar’s video:
- It’s joyful. I watched it without thinking about “should it be
let
orconst
?” or “should it be a typed array?” or “what is the right module structure” or “what is the best way to set up the build system?” It gets right to the point — let’s implement a simulation! - It simulates forces that are independent of distance but have a distance limit. I think the closest force we have to that is the Strong force[4], which is for the quarks inside an atom nucleus. If the goal is artificial life simulation, I’d want to use some force that depends on distance, like 1/d² (gravity, electromagnetism in a 3d world), 1/d (gravity or electromagnetism in a 2d world), Van der Waals forces[5] which can take into account the size of the particles, or Lennard-Jones[6] which is the force between molecules. The interesting thing with Lennard-Jones is that at close distances it pushes molecules apart and at far distances it pulls them closer. This can create really interesting patterns. There is also a generalization of Lennard-Jones called Mie potential[7] that might be useful for adapting Lennard-Jones for use in 2d. [github issue[8]]
- Since the forces are independent of distance, what’s really happening is that all the particles are moving towards (or away from) the center of mass of the other particles. If it weren’t for the distance limit, this would allow us to reduce an O(N²) algorithm with an O(N) algorithm — first compute the center of mass, then tell all the particles to move towards it. But with the distance limit, we’re looking for the center of mass of nearby particles. This is similar to flocking rather than atomic forces.
- The simulation writes into the input array instead of having a separate output array (double buffering), which means the order of the particles affects the output. This is ok with small timesteps but this simulation uses large timesteps. [github issue[9]]
- The bounds checking is insufficient for keeping particles inside the box. I fixed this in my code. [github issue[10]]
- The Euler integration is unstable, and the time steps are too large. I considered fixing these, but I think some of the cool effects are really simulation artifacts and not the results of the physics, so fixing them would make it less fun!
Despite these issues, it’s so joyful that I had a lot of fun playing with this. It’s a great introduction to this type of particle simulation!
The video has inspired lots of contributions to the original code, so check it out Hunar’s project github[11]. My page was inspired by the video but I developed it in a different direction, and my code is also on github[12].