Click and hold down the mouse, and move it up and down to alter the angle the blackhole is viewed at.
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.
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.
At every time step we integrate the positions of the particles forward in
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:
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
the fewer errors you will get. 0.1 seems to be a fairly reasonable first value.
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.