Now imagine that another cloud comes along and merges with our first cloud. Both have their own levels of water vapour at given points. Now it is possible that there are areas in these two clouds where two water levels that were previously invisible now overlap. The water levels combine to give a new level which now becomes invisble. As the two clouds pass through one another we see a continuously-changing pattern.
Exactly the same principle is used in the code to
produce blobs. At any given point we simply sum the "densities"
of all the elements in our system and plot the outcome.
The density value is each case will range from 0 to 1. A value of 0 means that at this point there will be no effect from the blob. A value of 1 is the maximum density allowed: when summing our densities, any resultant value above 1 will simply be treated as 1.
For the sake of simplicity and prettiness, we will only model our process around circular blobs. First we choose a value max_r for the maximum radius of the blob. This is the distance from the centre further than which the blob will have no effect at all.
Now we can apply our algorithm to determine the density at each point of our blob. In simple pseudocode, this is:
!------------------------------------------------------------
! x and y are the co-ordinate
values given as input
LET distance = sqr (
x*x + y*y) !Calc distance from centre
IF distance > max_r
THEN
LET density
= 0
!Outside max_r, density=0
ELSE
LET fraction
= (distance/max_r)
!Convert distance to the
!range 0 to 1
LET density
= (1-fraction^2) ^ 4
!calculate density function
ENDIF
!------------------------------------------------------------
Fig 1. Simple density function
The line "LET density = (1-fraction^2) ^ 4" is the interesting one.
Firstly, it takes the value fraction and firstly converts it to a value equal to 1 at the very centre of the blob and 0 at the edge of max_r, but the function tails off increasingly quickly as we reach the outer reaches of the blob.
Secondly, the second part of this assignment statement accentuates the tail-off of density as we reach the outside even more. This is to give a smoother effect when two or more blobs combine.
Some of you might wonder why the power used here is "^4" rather than "^2" This is because we are working in two dimensions rather than three. Without going into the maths too deeply, our model here is a two-dimensional cross-section of a 3D model, so repeating the squaring of our density function is a simple way of reducing the calculations to 2 dimensions.
!------------------------------------------------------------
! x and y are the co-ordinate
values given as input
LET distance_squared
= x*x + y*y
IF distance_squared
> max_r*max_r THEN
LET density
= 0
!Outside max_r, density=0
ELSE
LET fraction_squared
= (distance_squared/max_r/max_r)
LET density
= (1-fraction_squared) ^ 4
!calculate density function
ENDIF
!------------------------------------------------------------
Fig 2. Revised density function.
This is also available in "BLOB2" to show that it gives the same result.
Note the use of "fraction_squared" as a result of the substitutions. This is because
fraction = distance
--------
max_r
but
distance_squared = distance.distance
= distance distance
----------------
----------------- -------- . --------
max_r .
max_r max_r.max_r
max_r max_r
(Basic GCSE Maths, apparently)
- which is equal to "fraction" squared.
Here are the original lines we need to change:
LET fraction_squared
= (distance_squared/max_r/max_r)
LET density
= (1-fraction_squared) ^ 4
fraction_squared still ranges from 0 to 1. If we make it range from, say 0 to 255 by multiplying distance_squared by 256 before we start - not unreasonable for assembler - the result in "density" will range from 0 to 256^4-1 (ie a long word value in assembler)
LET fraction_squared
= 256*distance_squared/max_r/max_r)
LET density
= (1-fraction_squared)^4
We now have the whole function in a format useable in assembler:
!------------------------------------------------------------
! x and y are the co-ordinate
values given as input
LET distance_squared
= x*x + y*y
IF distance_squared
> max_r*max_r THEN
LET density
= 0
!Outside max_r, density=0
ELSE
LET fraction_squared
= 256*distance_squared/max_r/max_r)
LET density
= (1-fraction_squared)^4
!calculate density function
ENDIF
!------------------------------------------------------------
Fig 3. Assembler-useable density function.
Once this is written in assembler, we can store the
blob as a table and simply add two or more tables together
to create animated blobs. If I have time in the coming week
there will be a small ST intro to this issue of Maggie which does
this in realtime.
Steven Tattersall
12/10/97