|
|
---------------------------------------------------------------------------- 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 ---------------------------------------------------------------------------- |
|