
Java applets 1–5 January 2005
Nine versions of the applet, Galaxy2, written over the first five days of January 2005. Drag the mouse over an applet to add matter.

Version 0.01: distorts image as you draw 1 January 2005
Galaxy2Version 0.02: supposed to be gravity but looks nice anyway 1 January 2005
Galaxy2Version 0.03: great when you get it really going! 1 January 2005
Galaxy2Version 0.04: antigrav, grow your own bacteria 1 January 2005
Galaxy2Version 0.05: mad mould 1 January 2005
Galaxy2Version 0.06: working gravity, fudged 1 January 2005
Galaxy2Version 0.07: proper gravity at last, I think 1 January 2005
This version
2005-01-03
ood2 is now pre-multiplied into dirx and diry
Galaxy2v6 2 January 2005
Galaxy2Version 0.08: perfected gravity, slow n^4 method 5 January 2005
This version
2005-01-03
ood2 is now pre-multiplied into dirx and diry
took out wrap-around from calculations
Galaxy2Basic gravity simulation 4 January – 12 November 2005
This is a simple animation framework set up for doing the galaxy simulation. It is a Win32 C++ program built on the FFTW library; each version keeps its notes in a comment at the top of Pattern.cpp.

Simple framework 4 January 2005
uses fft fluid solver with gravity forcefield
todo:
use forward projection instead of sime-lagrangian lookups
Proper calculation, O(n^4) 5 January 2005
In this version:
use forward projection instead of sime-lagrangian lookups
combine ood2 lookup with dirx and diry
Past mass lookup 24 March 2005
This version:
Made gravity travel at the speed of light instead of infitiely fast
Method:
Store previous mass frames
Instead of using current mass frame for each pixel's calculation use a past mass
frame depending on the distance of the pixel from the one it is affecting.
I'll call the technique Pass Mass Lookup
Some different values followed on 31 March.
Proper working gravity at last 4 April 2005
pprizm (prizm ep) - i miss u already (benbecular label, scotland, techno)
This version:
woohoo - looks like i can do gravity using fft
I've had to negate the gravity strength and swap the x and the y lookups for some unknown reason
Then a nice single galaxy the same day, a good interface and various speed improvements on 5 April, “all working, happy” at 512 and at 128 on 11 May, and universal expansion added on 12 November.
Source
- Simple framework, 4 Jan: Main.cpp · Pattern.cpp · Pattern.h
- Proper calculation, O(n^4), 5 Jan: Main.cpp · Pattern.cpp · Pattern.h · pattern2.cpp · script.txt
- Past mass lookup, 24 Mar: Main.cpp · Pattern.cpp · Pattern.h · pattern2.cpp · script.txt
- Some different values, 31 Mar: Main.cpp · Pattern.cpp · Pattern.h · pattern2.cpp · script.txt
- Proper working gravity at last, 4 Apr: Main.cpp · Pattern.cpp · Pattern.h · pattern2.cpp · conv.cpp · conv.h
- Nice single galaxy, 4 Apr: Main.cpp · Pattern.cpp · Pattern.h · pattern2.cpp · conv.cpp · conv.h
- Good interface, various speed improvements, 5 Apr: Main.cpp · Pattern.cpp · Pattern.h · pattern2.cpp · conv.cpp · conv.h
- All working, happy, 512, 11 May: Main.cpp · Pattern.cpp · Pattern.h · pattern2.cpp · conv.cpp · conv.h
- All working, happy, 128, 11 May: Main.cpp · Pattern.cpp · Pattern.h · pattern2.cpp · conv.cpp · conv.h · resource.h · resource.rc
- Adding universal expansion, 12 Nov: Main.cpp · Pattern.cpp · Pattern.h · pattern2.cpp · conv.cpp · conv.h · resource.h · resource.rc
Using FFT to simulate gravity 5 April 2005
Operation
-
The universe is DIM x DIM, and DIM must be a power of two.
The universe is tiling (wraps around at the edges)
(because it uses &(DIM-1) as a quick way of wrapping around,
and because the FFT expects powers of two (i think) )
The universe is represented by a mass and an x and y direction (velocity)
for each pixel in a DIM x DIM square.
The gravity calculation involves calculating the force on each pixel
from the rest of the universe:
for each pixel A
{
force_x = 0
force_y = 0
for each pixel B except A
{
force_x += horizontal force on pixel A of pixel B
force_y += vertical force on pixel A of pixel B
}
// (force_x, force_y) is the total force on this pixel
// from the rest of the universe
}
After the force is calculated it is used to modify the velocity of the pixel.
Because the universe wraps around, each of the other copies of the universe
has an influence.
for each pixel A
{
force_x = 0
force_y = 0
for each tile
{
for each pixel B except A // i think you need to include A in all galaxies apart from real one?
{
force_x += horizontal force on pixel A of pixel B
force_y += vertical force on pixel A of pixel B
}
}
// (force_x, force_y) is the total force on this pixel
// from the rest of the universe
}
The force is a convolution of the mass array and the gravity force array.
To move the mass based on the force, start with an empty array (zero's)
NEW_MASS = zero array
for each pixel
{
M,DX,DY = pixel's mass and velocity
NEW_X = pixel's x position + DX
NEW_Y = pixel's y position + DY
Place mass and velocity into NEW_MASS with sub-pixel accuracy
}
To do a fast convolution of A and B (both power of two
The full sequence is:
Create gravity lookup tables LOOKUPX and LOOKUPY
each frame
{
FORCE_X = convolution of LOOKUPX and MASS
FORCE_Y = convolution of LOOKUPY and MASS
Apply FORCE_X,FORCE_Y to MASS
}
Create gravity lookup tables LOOKUPX and LOOKUPY
Calculate fft of LOOKUPX as V0
Calculate fft of LOOKUPY as V1
each frame
{
}
The gravity force array can be precalculated and saved off.
Notes
-
. Horizontal and vertical bias because of the grid nature of the universe
. Horiz and vertical streams coming out of tiny heavy galaxies when matter should be fired out in all directions
. Long thin galaxies form which suspiciously travel exactly in the x or y dir
Out-takes January – November 2005
Interesting visual effects when things go wrong. Two of them record steps towards the FFT version. From 6 January:
003:
use forward projection instead of sime-lagrangian lookups
combine ood2 lookup with dirx and diry
004:
use fft image convolution to calculate gravity (avoids n^4 calc and reduces it to n^2)
And from 31 March, “broke it whilst putting in FFT”:
007
trying FFT for gravity convolution
just put init_fft in, need to calculate kernel etc.
Source
- Not gravity, but nice effect anyway, 4 Jan: Main.cpp · Pattern.cpp · Pattern.h
- Another variation, 5 Jan: Main.cpp · Pattern.cpp · Pattern.h · pattern2.cpp · script.txt
- Hmm, 6 Jan: Main.cpp · Pattern.cpp · Pattern.h · pattern2.cpp · script.txt
- Broke it whilst putting in FFT, 31 Mar: Main.cpp · Pattern.cpp · Copy of Pattern.cpp · Pattern.h · pattern2.cpp · script.txt
- FFT but negative force(!), 1 Apr: Main.cpp · Pattern.cpp · Pattern.h · pattern2.cpp · conv.cpp · conv.h · script.txt
- Weird streaks, 1 Apr: Main.cpp · Pattern.cpp · Pattern.h · pattern2.cpp · conv.cpp · conv.h · script.txt
- Interesting effect caused by symmetrical force field, 3 Apr: Main.cpp · Pattern.cpp · Pattern.h · pattern2.cpp · conv.cpp · conv.h · script.txt
- Another variation, 4 Apr: Main.cpp · Pattern.cpp · Pattern.h · pattern2.cpp · conv.cpp · conv.h · script.txt
- Negative gravity, 12 Nov: Main.cpp · Pattern.cpp · Pattern.h · pattern2.cpp · conv.cpp · conv.h · resource.h · resource.rc
- Another variation, 12 Nov: Main.cpp · Pattern.cpp · Pattern.h · pattern2.cpp · conv.cpp · conv.h · resource.h · resource.rc
- Decreasing gravitational force, 13 Nov: Main.cpp · Pattern.cpp · Pattern.h · pattern2.cpp · conv.cpp · conv.h · resource.h · resource.rc
- Another variation, 13 Nov: Main.cpp · Pattern.cpp · Pattern.h · pattern2.cpp · conv.cpp · conv.h · resource.h · resource.rc
- Negative velocity damping weirdness, 13 Nov: Main.cpp · Pattern.cpp · Pattern.h · pattern2.cpp · conv.cpp · conv.h · resource.h · resource.rc
- Negative gravity change, 13 Nov: Main.cpp · Pattern.cpp · Pattern.h · pattern2.cpp · conv.cpp · conv.h · resource.h · resource.rc
3D visualisations 13 November 2005 – 23 May 2006
A 3D view of the simulation in November 2005, then a 2D galaxy with a 3D timestack in May 2006, with improvements the same day.
Source
- 3D view, 13 Nov 2005: Main.cpp · Pattern.cpp · Pattern.h · pattern2.cpp · conv.cpp · conv.h · resource.h · resource.rc
- 2D galaxy with 3D timestack, 23 May 2006: Main.cpp · Pattern.cpp · Pattern.h · pattern2.cpp · conv.cpp · conv.h · fftw.h · rfftw.h
- Improvements, 23 May 2006: Main.cpp · Pattern.cpp · Pattern.h · pattern2.cpp · conv.cpp · conv.h · fftw.h · rfftw.h