Gravitas is a collection of orbital mechanics simualations. Right now, I have n-body gravity and hohmann transfer simulations. I hope to add lagrange points simulation in a future update.
Live Demo: https://gravitas-eta.vercel.app/
I like physics and math and plan to major in either one in the future. I also have college applications coming up. This made a great personal project to showcase my passion!
The n-body gravity problem asks: given N objects that all gravitationally attract each other at the same time, how do they move?
Unlike the two-body problem (one planet and one star), there is no closed form solution for N ≥ 3 bodies, so you have to simulate it step by step.
This simulation has 7 presets, for all presets, you can zoom, pan and add new bodies by clicking the canvas to see how they affect the system (collision, merges, ejected out of the system). You can also toggle trails, velocity vectors, grid, and switch between RK4 and Verlet integrator.
The solar system presets lets you run the full solar system, in which, every planet exerts a gravitational force on every other planet, in every frame, and the positions are updated accordingly.
Most of the stars in the universe aren't alone. They exist in binary systems, two stars orbiting their shared centre of mass (barycentre), not each other directly. This preset has two stars of different masses orbiting their barycentre.
For this, let's go back to the question asked for N-body Simulation as a whole, but taking n as 3.
The three-body problem asks: given three objects who exert a gravitational pull on each other, how do they move? In general, we don't have a closed=form solution or asnwer for that, as stated at the beginning. But in 2000, Chanciner and Montgomery proved that there exists one special solution where three equal masses follow each other around a 'figure-8' path forever, and its also perfectly periodic! This simulation runs this.
A galaxy is a large collection of stars orbiting a massive core at the centre. This simulation has two such galaxies, each with about 280 stars, on a path to collision. As they pass through each other, the gravitational pull of one galaxy disrupts the orbits of the stars in the other galax and flings them out into tidal trails and streams.
When a massive star exhausts its fuel, the core collapses and the outer later are blasted outward. Left behind, is a dense remanant (neutron star or black hole). This simulation starts right after that explosion, with a remanant at the centre, and shells of debris flying outward. The remanant's gravits gradually pulls some of it back, but the fastest fragments escape.
A pulsar is a really fast rotating neutron star that fires jets of charged particles from its magentic poles. This simulation has a fixed neutron star at the centre with two opposite jets, and an accretion disk of matter falling inward orbiting around it.
A Hohmann Transfer is a two-burn maneuver thats moves a spacecraft between two circular orbits using the minimum possible change in velocity (hence, most efficient way). The first burn is to leave the first orbit and enter an elliptical transfer orbit, and the second burn, when the spacecraft arrives at the second orbit, to circularise.
This simulation calculates the two burns, transfer time, phase angle for any two planetary orbits (in planet mode), and animates the spacecraft travelling the path. Satellite mode does the same for orbits around any solar system body, in km, and allows you to change the altitude and inclination as well.
The n-body problem asks how N objects move under gravitational forces, but what about a point where an object stays still?
In the rotating reference frame of a two body system (consider Sun-Earth), there are five points where gravity from both bodies and the centrifugal force (psuedo-force) of the frame all cancel out.
L1, L2 and L3 all lie along the line joining the two bodies in the system. These points are unstable. L4 and L5 sit 60° ahead and behind the smaller/secondary body (Earth in this case). These two points are stable, which is why approx. 7,000 Trojan asteroids have collected at Jupiter's L4 and L5 points.
This simualation visualises these five lagrange points for five systems (Sun-Earth, Earth-Moon, Sun-Jupiter, Sun-Mars, Sun-Venus) and shows a heatmap for effective potential in the background as well. The secondary body is also animated, and orbits around the primary body.
git clone https://github.com/Hiba-Malkan/gravitas.git
cd gravitas
python3 -m http.server 8080Then open http://localhost:8080 in your browser.
Or open index.html directly, no need for starting the server.
- HTML
- CSS
- Javascript
Force between every pair of bodies, all added together. G = 4π² in AU.
A small ε² term added to the distance to prevent the force from tending to infinity during close encounters (so accelaration doesn't tend to infinity and bodies don't go zooming across the canvas). Used ε = 0.001 AU.
4th order Runge-Kutta integrator evaluates the derivative at 4 points per step and takes a weighed average. This keeps orbits stable long term unlike the Euler method I was previously using.
This is an alternative integrator to RK4. The difference is how the velocity is updated. Instead of using only the accelaration at the start of the step, it takes the average of the accelarations at the start and end of the step. This makes it symplectic, which means it preserves the geometric structure of the physics, so energy doesn't leak in and out of the system the way is does with non-symplectic ways like RK4. Verlet is suited for large body systems, like supernova and galaxy collision, where RK4 would be very slow.
In a n-body simulation every body pulls every other body. We already know that, but that means n² force calculation per step, which becomes very slow for a large n. Hence why, we need Barnes-Hut. It solves this problem by grouping distant bodies together. All the bodies are inserted into a quadtree (a tree that recursively divides 2D space into four cells). When calculating the force on a body, if the cell is far enough away the entire cell is approximated as a single body sitting at its centre of mass. This brings it from O(n²) to O(n log n), which makes galaxy collisions and supernova actually be able to run in a browser and not lag a lot.
Used to set the orbital speed for each body of the accretion disk. A small eccentricity is also applied so that the orbits are slightly elliptical rather than perfectly circular.
Vis-viva equation gives the speed of an object at distance r from the central body, in an orbit with a semi-major axis, a. This is used for all Hohmann Transfer velocity calculations. For a circular orbit r = a, so the equation simplifies to v = √(GM/r).
Semi-major axis of the transfer ellipse is:
Delta-v (change in velocity) at each burn is calcualted using the vis-viva difference between circular velocity and transfer ellipse velocity at each endpoint.
Transfer time, then, (half of the period of the ellipse):
Phase angle is the specific angular separation required between a spacecraft and its target planet (or two planets) at the moment of launch to ensure they meet at the destination after a Hohmann transfer orbit (defination taken from Google AI overview).
M is mean anomaly (linear in time), E is eccentric anomaly , e is eccentricity. This has no closed-form solution and hence is solved numerically using Newtons-Raphson iteration. It is used to compute the spacecraft's position on the ellipse at each animation frame.
True anomaly from eccentric anomaly:
Used in the simulation to combine the plane change with the circularisation burn using the law of cosines:
Tracked to ensure that energy doesn't drift significantly and the integator does not continue to accumulate error. In a perfect scenario this would never work, but in practice, it should only drift slightly.
In the rotating reference frame, the effective potential adds gravity from both bodies with the centrifugal term.
L4 and L5 are stable only if the mass ratio is above 24.96 (or approx. 25). L1, L2, L3 are always unstable and have no closed form solution so it is solved numerically using Newton-Raphson method (same method as Kepler's eq. stated before).
RK4 implementation : to evaluate the derivative at an intermediate point you have to temporarily move all the bodies to their intermediate positions, calc. forces and then restore them before the next substep. I forgot to restore the bodies and they started teleporting.
Binary stars initial conditions : both the stars in the preset needed to orbit their shared barycentre, not the origin. so, getting the velocities required wroking out the relative circular orbital speed and them splitting it proportionally by mass.
Spacecraft Animation : I was using const. angular speed around the ellipse, and this does not follow Kepler's second law (Law of Areas- equal area swept in equal time). I had to convert mean anomaly to true anomaly using Newton-Raphson method.
Canvas sizing: offsetWidth returns zero when a panel is just made visible. fix was a requestAnimationFrame delay before measuring (this took a lot of time to figure out for how insignificant this was).
AI Usage:
Used AI to validate code to the effect that it followed the laws of physics. Used github's copilot for code autocompletion (however time spent by using copilot autocomplete is not tracked by Hackatime anyway).
Used Google's AI Overview for equations used in this readme (the way they're written in the readme?)
Built for Hack Club, Flavortown
Created: 20 March, 2026