Blackhole Simulation

this should be a java applet.

Directions

Click and hold down the mouse, and move it up and down to alter the angle the blackhole is viewed at.

Source Code

Simulating blackholes

I saw on slashdot a link to an article at oreilly.net about simulating black holes in opengl. It caught my imagination and decided that I'd write my own version, in java of course. The article was quite interesting, but focused more on how to do the opengl side of things, which was probably fair as that was probably more tricky than the physics involved.

In the article they used particle physics (objects that have a position, but don't rotate) to simulate particles being sucked into a black hole. Basically they had 1000 particles that were spat out into the space around the blackhole. They are spat out gradually and when the particles either reach a certain speed or a certain distance away from the blackhole they are removed from the system and reintroduced at the edges again.

Physics

So now I'll give a brief guide to the physics involved. First off we'll make a couple of assumptions, some of which are to help save a few calculations.

  • All particles have mass 1
  • The blackhole is centred at the origin ( point (0,0,0) )
  • All particles have a position (x,y,z)
  • All particles have a velocity (vx,vy,vz)
  • Particles do not "interact" with each other, they are only affected by the blackhole

At every time step we integrate the positions of the particles forward in time by dt seconds. i.e.


x = x + dt*vx
y = y + dt*vy
z = z + dt*vz

Then we see if the particle is within a certain distance from the blackhole (at (0,0,0)) and put the particle back to the edge if it is:


distSq = x*x + y*y + z*z
if ( distSq < cutOffDistance*cutOffDistance )
... reinitialise at edge

Next we need to update the particles velocity. There are two things that will influence the velocity of the particle:

  • The effect of gravity from the blackhole
  • and friction, to ensure that the particle will fall into the blackhole

So to simulate the effects of gravity from the black hole we first need to calculate how large the force is. Gravity varies with the inverse of the square of the distance, i.e. as the distance between two objects doubles the gravitational attraction between them halves. Blackholes are supposed to be very very massive, and the particles will be comparatively very small in size. It is therefore fairly reasonable to neglect the effect of the particles on the blackhole.

We then need to apply this force to the particle in the correct direction. If we calculate the direction vector and multiply this by the force we have calculated, we'll have the force for each direction x,y,z.


distSq = x*x + y*y + z*z
force = -10000/distSq //negative, so towards blackhole
dist = sqrt( distSq )
fx = x/dist
fy = y/dist
fz = z/dist
vx = vx + dt*fx
vy = vy + dt*fy
vz = vz + dt*fz
// next apply friction
vx = vx*0.999
vy = vy*0.999
vz = vz*0.999

Then we check to see if the velocity is too high, if it is we remove the particle and reinitialise it at the edge. It is fairly important that we check the speed, as when a particle starts moving too fast it may gain energy, due to integration errors, which results in the particle falling towards the blackhole, then getting an energy boost and flying off screen in a very unrealistic manner. Generally speaking the smaller the size of dt the fewer errors you will get. 0.1 seems to be a fairly reasonable first value.

Displaying it all

I wanted my program to run fast and in java, so to display the effects I chose to use parallel projection. By that I mean I discarded the z coordinate and just plotted the particles x and y coordinates as if they were normal points in 2D.

This looks o.k. in this situation as we can be assumed to be viewing the blackhole from very far away, where the difference in distance (z coord) between particles can be assumed to be relatively small.

I also took the extra step of drawing the particles as anti-aliased dots, rather than just white pixels (see Hugo Elias's page) so that when they are moving slowly they won't jump from pixel to pixel, but will glide between them (well that's the idea).

Also the particles are slightly transparent, so that they will add together, making the area they appear in get whiter the higher the concentration of particles.