Alive
News Team Current issue History Online Support Download Forum @Pouet

01 - 02 - SE - 03 - 04 - 05 - 06 - 07 - 08 - 09 - 10 - 11 - 12 - 13 - 14

Alive 9
----------------------------------------------------------------------------
low star galaxy model, by earx 2004
----------------------------------------------------------------------------

this article is based on the galaxy effect i did on atari falcon in 2002. a
friend wanted to do a port to pc, so i decided to dig it up, comment the
code and write a little article about it. this is not intended as an article
about astrophysics. the model is very unrealistic in this respect. it is
meant just to make it look 'nice' without fussy code or high hardware
requirements.

----------------------------------------------------------------------------
the concept
----------------------------------------------------------------------------

my idea was to have a galaxy based on spiral curves. that seems to go almost
without saying. however, i once saw an iterative algorithm that could make
a galaxy shape out of just totally random dots. i never got around to
understanding how that worked, though.
 also, needing an amount of iterations seemed a little awkward. i wanted to
be able to define the amount of arms and such with 1 parameter, and without
preprocessing.
 furthermore, i didn't find any information on generation of galaxy models
anywhere on the net. maybe i got poo in my eyes, i don't know, but i decided
to do it myself.

first, i tried 2d spiral plots, that was easy enough:

x=t*sin(a*t), y=t*cos(a*t) (0<t<1)

fig. 1:
left: basic 2d spiral curve, right: multiple curves/arms: a 'galaxy'


this is what i based the arm shape on. 'a' denotes the final angle. A big
'a' results in unclear shape of the arm: the points seem to lie randomly
in a circle. making it too small results in a very boring, almost straight
line. typically, you'd want to have 'a' on the large side.

now i wanted to fill the arm up. so, i tried to replace the points with star
spheres. these are just balls filled with stars. by varying the width of the
spheres we can make a realistic looking galaxy, where the arms are thin at
the ends and thick at the center.

the introduction of spheres gave rise to the following problem: how to get a
natural-looking spread of star density in the arm? we need high star density
in the arm center and lower density to the outside and this without too many
discontinuities. although, a totally regular look would not help realism
either. in turn, this trade-off gave birth to a new number of problems:

1. what should be the distribution of stars in the spheres? what coordinate
   system should be used? can the distribution be uniform? or perhaps more
   biased to the inside?

2. how should the spheres be spread? the spheres should overlap, but they
   have varying width, and a growing spiral has huge gaps between points on
   the outside but not on the inside, see fig. 4. so, we should adapt the
   distribution of these points.. also we still need to model the contained
   amount of stars and the width of each sphere.

----------------------------------------------------------------------------
1. star distribution (within a sphere)
----------------------------------------------------------------------------

a polar coordinate system was dismissed right away. as usual, concentration
of points along the poles is a bitch, and i didn't want to do any patching.
so, i decided to use a cartesian system. i generated random dots inside a
unit cube. every dot that fell outside the unit sphere was dismissed.

x=random(), y=random(), z=random()

    [x]
v = [y]
-   [z]

with:

|v|^2 = (x^2+y^2+z^2) < 1
 -

i discovered that a random (uniform) distribution causes the viewer to
perceive the sphere as flat and also too regular, especially for use in the
spiral arms. so, the logical conclusion was to bias the dots more towards
the center, like so:

v'=|v|*v

or

v'=|v|^2*v

and yes, that looked better. so that fixed this problem..

fig. 2
left: sphere with boring distribution, right: sphere with good distribution

----------------------------------------------------------------------------
2. sphere distribution, size and star count
----------------------------------------------------------------------------

it seems all galaxies are thicker in the center than on the outside. to keep
it simple, i decided to start with a fixed amount (n) of stars in the first
sphere (the one in the center) and then put n-1 in the next, n-2 in the one
after that, till there was just 1 star left for the final sphere.

i decided to control the width in much the same way. just decreasing it a
bit each step to the outside. i made the width depend directly on the sphere
index and i did the same for the angle and distance from the galaxy center.
let's write that down a little better:

the sphere index [1..n] determines:

a. the number of stars in the sphere
b. the sphere width
c. the angle of the spiral point
d. the distance of the spiral point from the galaxy center

where c and d form polar coordinates, this can be calculated back to
cartesian and may be used to translate the star spheres.

now, we were left with just one more problem for b, c and d. how to find
a decent function of the sphere index? this cost a lot of time to
experiment. as usual i ended up with some sine wave raped thing. this has
the advantage of being continuous to the umpteenth degree and all that:
in other words: 'it's smooth'.

this is what i ended up with:

t(i) = .5[cos(pi*i/n)+1] (i : [1..n])

where 'i' is the sphere index and 'n' is the number of spheres. this is
nothing more than an unsigned half cosine. note that i=1 means that we
are in the last sphere (on the outside of the spiral!).

fig. 3: the spread function (t)
left: linear spread function, right: sinoid spread function

fig. 4: effects of various spread functions on the arms
left: arm with (linear) boring spread, right: arm with good (sinoid) spread


now we use 't' to calculate b, c and d.

b.

r(i) = r_scale[r_start - t(i)] ( r_start > t(0) )

where 'r_start' is a constant and close to the maximum sphere radius. so,
the higher the index, the smaller the sphere.

c.

angle(i) = max_angle * t(i)

need we say more, just some scaling..

d.

distance(i) = max_dist * t(i)

ehm? what can i say?

to sum it up: the cartesian center coordinates of the star sphere

c.x = distance(i)*sin(angle(i))
    = max_dist * t(i) * sin [ max_angle * t(i) ]
c.y = distance(i)*cos(angle(i))
    = max_dist * t(i) * cos [ max_angle * t(i) ]
c.z = 0

----------------------------------------------------------------------------
putting it to use
----------------------------------------------------------------------------

the combined solutions to 1 and 2 seemed to produce very nice models of
galaxy arms. all i needed now was to produce a number of these arms with
rotation symmetry, for instance: we have 3 arms:

arm 1: 0 deg, arm 2: 120 deg, arm 3: 240 deg

using unique arms, i.e. not just copying and rotating one arm a few times,
gives slightly more realistic results.

some parameterisations that work nicely (i didn't even know anything about
galactic morphology at the time):

2 arms, max_angle = 10*pi/7 (very clear spiral form)
3 arms, max_angle = pi
3 arms, max_angle = 4*pi/3
4 arms, max_angle = 20*pi/9 (nice 'discy' thing)
4 arms, max_angle = pi
4 arms, max_angle = 8*pi/7

if you use 50 spheres per arm, it will already look okay. of course, it's
wise to have a little more: try 70.

to get the right sphere radius it's good to use 1.1 for the 'r_start'
parameter. to get the right depth/width ratio for a galaxy i chose:

max_dist / r_scale somewhere between 4 or 6.

i can't remember exactly, just experiment a bit.

----------------------------------------------------------------------------
implementation
----------------------------------------------------------------------------

the original code was done by me for 68030 (the generation) and for 68030
and 56001 dsp (transformation and visualisation). it was completely done
with fixed point and fractional numbers. the stars were visualised as
additive grey pixels. on a standard atari falcon there may be over 5000 on
screen at 50fps.

there is also an OpenGL port made by Tristan van Stijn, written in C++.

----------------------------------------------------------------------------
the future
----------------------------------------------------------------------------

maybe someone has a decent knowledge of astronomy and specifically knows
something about the morphology of galaxies. i'd like to know if any types
of galaxies unknown to me can be modelled with my algorithm as well..

also, i tried this effect with some grey additive pixels as stars, but i
guess some blended sprites, billboards, or whatever they are called today,
will look better.

of course, if anyone did a similar algorithm, i'd like to know about it.

to contact me, try snailmail:

Pieter van der Meer (earx/lineout)
Ridderstraat 120
4101BK Culemborg
The Netherlands

or you can try e-mail:

pietervdmeer[at]netscape.net

----------------------------------------------------------------------------
some additional useful statistics (counting stars)
----------------------------------------------------------------------------

n : amount of spheres in one arm
    this directly determines amount of stars in an arm...

stars in arm = n+n-1+n-2+...+2+1 = n(n+1)/2

so, the first sphere has n stars.
this is the sphere most in the center: it has the highest amount of stars
and is the widest too. the spheres further away from the center are less
wide and contain less stars. The sphere at the end of an arm contains only
1 star.

arms : amount of arms

total amount of stars = arms * stars in arm = arms * n*(n+1)/2

if we have a 2 arm with 50 spheres per arm: 50*51/2*2=50*51  =2550 stars
if we have a 4 arm with 70 spheres per arm: 70*71/2*4=70*71*2=9940 stars

----------------------------------------------------------------------------

Alive 9