Programming

A galaxy far far away... in your browser

Kaj Siebert

A rare clear night a couple of weeks ago, I managed to capture this image of the Whirlpool Galaxy with my Unistellar eVscope.

A telescope image of the Whirlpool Galaxy.

Seeing these two interacting galaxies reminded me of something from my digital past. In the 1990s, many of us who worked on unix workstations were familiar with the “xscreensaver” collection, and one program in particular, galaxy, stood out. It was a simulation of galaxies colliding, and I could watch the spirals of light dance and merge for hours.

Inspired by my new telescope image, I decided to revisit this piece of software. I wanted to understand how it worked, modernize it, and share it with a new generation. This project, a JavaScript port of the original galaxy simulation, is the result of that journey.

A Trip Down Memory Lane

This code has a long and storied history, evolving through several platforms and authors. Full credit belongs to the creators and contributors who have maintained this program over the decades.

  • Original Author: The simulation was first written by Uli Siegmund on an Amiga for EGS in Cluster.
  • Early Ports: It was subsequently ported to C/Intuition by Harald Backert.
  • X11 and Xlockmore: The version most of us remember was ported to X11 and incorporated into the xlockmore screensaver collection by Hubert Feyrer in 1994.

My goal was to build on this legacy, creating something that was not just a visualization, but a true simulator that could be used for educational purposes and as a foundation for other creative projects.

The Ghost in the Machine: The Physics of the Cosmos

What makes the galaxy simulation so captivating is that its complex, life-like behavior emerges from a few simple physical laws. It’s a beautiful example of emergence in a computational system.

The simulation is, at its heart, a simplified n-body calculation. It models a system of massive central bodies (think super-massive black holes) and a vast number of massless “stars” that are influenced by their gravity.

Here are the key simplifications that make the simulation computationally feasible, even in a web browser:

  1. Massless Stars: The gravitational pull of each galaxy’s central mass on every single star is calculated, which is a lot of work! To simplify, the gravitational forces between individual stars are ignored. They are treated as massless points that only react to the big players.
  2. Galaxy-to-Galaxy Interaction: The gravitational forces between the central masses of the galaxies themselves are calculated. This is what causes the galaxies to orbit, interact, and perform their stunning mergers.

The force itself is calculated using Newton’s Law of Universal Gravitation (F=Gm1m2r2F = G \frac{m_1 m_2}{r^2}). To translate this force into motion, the simulation uses a numerical integration method called Symplectic Euler integration. Unlike simpler methods that can “leak” energy over time, causing orbits to become unstable, the Symplectic Euler method is remarkably stable, which is crucial for keeping the galaxies from flying apart over long periods.

For each object, every frame, the simulation follows these steps:

1. Calculate Acceleration (a): It calculates the total gravitational acceleration on an object by summing the forces from all massive bodies.

a=GMr3r\vec{a} = G \frac{M}{r^3} \vec{r}

2. Update Velocity (v): It updates the object’s velocity based on this acceleration.

vnew=vold+aΔt\vec{v}_{new} = \vec{v}_{old} + \vec{a} \cdot \Delta t

3. Update Position (p): It updates the object’s position using the new velocity. This is the secret sauce of the Symplectic Euler method’s stability.

pnew=pold+vnewΔt\vec{p}_{new} = \vec{p}_{old} + \vec{v}_{new} \cdot \Delta t

This simple loop, repeated thousands of times, gives rise to the beautiful, organic motion that has captivated so many of us.

A Modern, Modular Cosmos

In porting this classic, I wanted to make it as flexible and extensible as possible. The original was a monolithic C file; this new version is built as a series of modular components that can be mixed, matched, and extended.

Pluggable Physics & Rendering

The core simulation logic is decoupled from the rendering. You can use the provided 2D canvas renderer for a lightweight, classic feel, or you can plug in a more advanced 3D renderer like THREE.js for a more immersive experience.

The physics engine itself is also pluggable. The galaxy-simulation web component accepts a simulator object. While it defaults to the Symplectic Euler method, you could provide your own object with an updateGalaxies method to implement different physics—perhaps a Leapfrog integrator, or even something completely non-Newtonian!

Extensible Celestial Bodies

The Galaxy and Star objects are simple classes designed to be extended. They each have a data property, which is an open-ended object where you can store any additional information you need. For example, you could track the age of a star, its spectral type, or whether it belongs to a globular cluster.

// Example of extending a galaxy object
const myGalaxy = createRandomGalaxy({ minStarCount: 500 });

// Add custom data
myGalaxy.data.type = 'Spiral';
myGalaxy.data.hasActiveQuasar = true;
myGalaxy.stars.forEach(star => {
  star.data.age = Math.random() * 10e9; // Give each star a random age
});

This allows you to build more complex simulations on top of the core physics engine.

Bring the Galaxy to Your Website

I’ve packaged the simulation into easy-to-use web components. You can drop a galaxy simulation onto your own web page with just a few lines of HTML.

The Lightweight Version

For a simple, no-fuss 2D canvas version that captures the spirit of the original, you can use the galaxy-simulation component.

<html>
    <head>
        <title>Galaxies</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script src="https://unpkg.com/@kajws/galaxy-js"></script>
    </head>
    <body>
        <h1>Galaxies</h1>
        <galaxy-simulation style="width: 600px; height: 400px;" >
    </body>
</html>

And just like that, you have a beautiful, animated galaxy simulation running on your page.

The Full 3D/VR Experience

For a more immersive experience, you can use the vr-galaxy-simulation component from the separate project @kajws/galaxy-vr). This component
uses THREE.js for 3D rendering and supports WebXR for virtual reality.

Then, add it to your page. This component offers more configuration options, such as the number of galaxies and whether to show a background starfield.

<html>
    <head>
        <title>Galaxies</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script src="https://unpkg.com/@kajws/galaxy-vr"></script>
    </head>
    <body>
        <h1>Galaxies</h1>
        <vr-galaxy-simulation 
          galaxy-count="3" 
          max-galaxy-count="7" 
          show-starfield 
          auto-orbit
        ></vr-galaxy-simulation>
    </body>
</html>

This gives you a fully interactive 3D scene that you can explore with your mouse, or with a VR headset for a truly breathtaking view from inside the galactic dance.

Conclusion

This project has been a deeply rewarding journey into my own past and into the elegant physics that govern the cosmos. I hope that by modernizing this classic and making it accessible and extensible, I can inspire others to explore, learn, and create their own beautiful simulations. The universe is at your fingertips!

Related posts