Go with Simple Direct Layer
This is a basic implementation of a particle simulation with gravity. The simulation is crude and mildly inefficient but works as a proof of concept. Some basic interaction is implemented using the keyboard, and the use of SDL2 should make this application portable to almost any device.
In all cases, use the -h
flag to get more help on how to use the application.
Note that building the SDL2 library can take a long time - for me it took close to five minutes. This is a one time compilation however, and subsequent runs will not require this lengthy step.
go run .
First, build using
go build .
Then run the application with
./gravity_simulation
While the simulation is running you can use the keyboard to control parts of the application. The controls are:
- W : Move view window up
- A : Move view window left
- S : Move view window down
- D : Move view window right
- Q : Zoom out
- E : Zoom in
- ArrowKeyDown : Decrease the rate of view window movement
- ArrowKeyUp : Increase the rate of view window movement
- ArrowKeyLeft : Decrease the speed of the simulation
- ArrowKeyRight : Increase the speed of the simulation
- Spacebar : Toggle pause/resume
- X : Toggle particle trails
- C : Advance a single timestep (without unpausing)
- P : Print the current state of the simulation (all bodies + settings)
- O : Save the currect state of the simulation
The main goal of this project was to:
- Use Go for a complex application
- Use a graphics framework in Go
On these fronts, the project has been a resounding success. However, there is still some work that could be done to improve the application.
The physics calculations performed at each step is somewhat inefficient. Currently the program calculates the force contribution on a Body from all other Bodies before summing this up and finding the resulting acceleration. Then, a small step is made to simulate a continuous flow of time. This is fine for small simulations (numBodies <= 100) but the computation grows with O(n^2). There are some techniques that could significantly improve performance here:
If we note that the force on Body A from Body B is exactly equal but opposite to the force on Body B from Body A we can immediately cut out exactly half of the expensive force calculations. This would provide an immediate speed up by a factor of 2 and may not be very difficult to implement. However, scaling is still O(n^2)
A quadtree is a data structure that splits space into quadrants recursively until nothing of interest remains in a leaf. In this application a quadtree is useful as for a body in a quadrant, all bodies outside of a quadrant can act like a single body instead of many individual bodies. This would reduce the number of computations immensely and result in a much more efficient computation at the cost of implementing and building a quadtree at every step.
A quadtree would allow for scaling like O(log(n)) instead of O(n)
Current interactivity is rather crude, as only the keyboard is used. It would be nice to make some the interactions use the mouse, or even support other devices for true portability.
It may be nice to have a good way to interact with the file system when saving/loading files, instead of hardcoding that saved files are saved to save.csv