I've had this idea kicking around in my head for years. The gist of it was "what if I made a simulation of gravity using cellular automata". Well, I finally got around to doing so. I'll give some technical details after, but here are some images of what came about:


This shows two fields blending together.


A heart-shaped block of mass causing interference patterns with itself.


Four "black holes" that developed.


Ended up fixing the blending of colors to get better spectrums.


It's just neat!


This inspires terrain generation.

The next few are just pretty:




Here are a few videos of it in action:







Technical details:
Mass and gravity are modeled as two 2D fields. The user inputs mass particles with a given mass, determined by the Divisor input (MaxMass / Divisor). As the simulation runs, it updates the gravity and mass fields based on each other. The mass field is conserved, meaning no particles will ever "disappear". The gravity field is calculated from the mass field and itself.

For each gravity cell, it looks at the mass field, and sets the gravity to MassValue shifted right by 3. It then takes the average of the gravity from all adjacent cells, and adds that to the current gravity from the mass field.

For each mass cell, it looks at the adjacent gravity field cells as well as its own gravitation field cell. It orders them by strength, and randomly picks the strongest gravitation to "fall" towards. This could mean "falling" toward its own cell, thus not moving. If a cell (other than itself) occupies the cell it tries to fall toward, it falls toward another random cell with the same gravitation strength. If all cells with the highest gravitational strength are occupied, it goes to the next strongest gravitational strength. It does this until there are no other cells, in which case it stays put.

You can find the code to this, and incidentally lots of other little toys I've made over the years, in my github: https://github.com/merthsoft/MooseLib/tree/main/GravityCa

If you want to play with it, here's a download link: https://merthsoft.com/GravityCA/Gravity.zip
Requires .net 8, should run anywhere with a .net 8 runtime (Windows, Mac, many Linuxes).

Controls:
Space - toggles simulation running or paused
Left click to add a mass with the current divisor
Right click to remove mass
Mose wheel adjusts the divisor
0 - Grayscale palette
1 - Rainbow palette
2- Two rainbows
3 - Three rainbows
4 - Four rainbows
5 - Six rainbows
6 - Eight rainbows
7 - Twelve rainbows
8 - Sixteen rainbows
9 - I dunno like sixhundred rainbows or somthing like that

1 through 0 on the number ROW (not numpad) will change the number of values used to render the gravity.

T - Draw debug text
M - Toggle mass renderer
G - Toggle gravity renderer
B - Toggle blending the colors between values

Z - Zero-out mass field
X - Zero-out gravity field
R - Randomly fill .01% of the remaining open mass field with the current divisor
F - Fill the mass field with the current divisor
I wasn't planning on revisiting this, but I ended up doing some work on it. It functions similarly, but there's been lots of optimizations and improvements. Here's a video:



Here's the code:
https://github.com/merthsoft/MooseLib/tree/main/GravityCa

Here's some stills:



This is a composite of the above two:


This one's my favorite so far:
I haven't looked into how this works much but the artifacts in the second, third, and fourth images remind me a lot of the sorts of problems you get because of the numeric instabilities inherent to erosion simulation.
I think you mean the dotting? Those are VERY high density mass spots that are driving the gravitational field very high at that point. In this iteration, I added a "vacuum energy" model. This causes lots of chaos, but a side effect is that the initial masses start to get very dense as they eat up all the newly spawning mass, which causes "stars" as seen there.
I added a 3D render mode. Lets you see black holes in action:


There's a release on github if you want to play with it:
https://github.com/merthsoft/MooseLib/releases/tag/gravity

Keys are:
https://github.com/merthsoft/MooseLib/blob/v0.6a/GravityCa/GravityGame.cs#L98

The 3D camera controls are bad right now.
Some more progress made:

Better camera controls. That's being controlled with a controller.

And a cube mode:


Question:
I want to accomplish two more things with the 3D renderer next:
1) More efficiently generate/reuse the VertexBuffer
2) Connect the cells when rendering (meaning, share vertices between adjacent cells)

The way I do the rendering right now, each time it renders, I then:

Code:

Assume VertexBuffer is TriangleList of VertexPositionColor
Clear VertexBuffer
For each (x,y) in the grid
    Get the gravity as a percent
    Get the color for the gravity based on that percent
    Insert into VertexBuffer Quad made of triangles (x, percent * 100, y) - (x + 1, percent*100, y + 1) with color


What I would like to do is on startup:

Code:

Assume VertexBuffer is TriangleList of VertexPositionColor // If possible, prefer TraingleStrip
Pre-build VertexBuffer with Triangles such that it creates a flat plane of transparent nodes connected to approximate a 2D grid of 1x1 cells

And then each render:

Code:

For each (x,y) in the grid
    Get the gravity as a percent
    Get the color for the gravity based on that percent
    Update appropriate vertices in VertexBuffer
        color = color
        y = percent * 100


I'm just not quite sure how to pre-generate the TriangleStrip (ideally) to accomplish the look I want and then the translation of (x, y) into appropriate VertexBuffer coordinates (I assume there will be several that I need to update per cell).
If you share vertices your quads will have internal color variation - if you want to keep the internal "flat shaded" effect you have now, then unfortunately you either have to duplicate vertices, or write some funky shader code to compute the color dynamically from the geometry GPU-side at render time.
What kind of internal color variation would occur? If it's a matter of blending between node colors, that would actually be able to save me some computation so might be useful. If it introduces more weirdness, that may even be a plus in terms of artistic usage.
I've got a few different ways to render it in 3D now. [url=https://imgur.com/a/JWJvbgk]here's an album[/img] of images and a sample of the deformed sheet:


And a demo:


And a download:
https://github.com/merthsoft/MooseLib/releases/tag/Gravity-v0.7a
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement