                        ҷ      
                         ַǷַַַ
                         ӶӽĽ
                        




I am not a person to release source-code, because (I don't believe I'm saying
this) you have to be careful of lamers. (In this case: lamers = people that
simply take routines from others, modify the text it displays and then link
it together to create a 'new' demo)
But to give those that are beginners (like me) a chance, I will include a
'TECH.TXT' in all my productions, describing all (or almost all) techniques
I have used in that demo.
I will try to explain clearly what I do, but should you not understand my
explanations (I wouldn't blame you... I have never been really good in
explaining), then you can always send me an email to ask me any question
about the techniques used (my email address is listed in 'CHOSEN.TXT').
If anything in these docs should prove wrong, please contact me...



 ҷ       
 кڷֶַַǷַַ
  ӽӽ ӽӽ


To know what the special properties of Mandelbrot-fractals are, and to know
how they are built, I recommend you to try and find a few books about fractals.
Most of those books contain an explanation of the formulas needed to calculate
a Mandelbrot-fractal. Since this topic is too big for this doc to handle, I
will only write some text about a technique that can speed up your calculations
a lot. If you want to know a little more about Mandelbrot fractals you can
always contact me for more information.

I assume you code in assembler, else you can skip this text, since it will 
hardly help you.

Since you don't have the luxury of floating point values in assembler (atleast
not when you don't have a coprocessor) you will have to substitute that by
another technique to store those numbers. The best trick I know to do that is
by using fixed point numbers. The idea behind it is very simple.
If you need a byte-value with a point in it, you can for example use a word
to place it in. You just use the lower eight bits as the fractional part of
the value. This way you can get fair accuracy, without having to use the
coprocessor. If you want a higher accuracy then you can use a dword value and
use the lower twentyfour bits as fractional part.
so for example:
	12.5			00001100 10000000
				(1*2^3+1*2^2+1*2^-1 = 8+4+0.5 = 12.5)
	12.3			00001100 01001100
		(1*2^3+1*2^2+1*2^-2+1*2^-5+1*2^-6 = 8+4+0.25+0.03125+0.015625
						  = 12.296875 (close enough))

How to get to these values? simple... if you have an accuracy of 8 bits, you
simple take the value you want and multiply it by 2^8=256 (if you don't believe
it... try it with a few values)

Calculating with these values is almost as simple as with normal integers.
addition and subtraction will result in the correct answer immediately. With
multiplication and division it unfortunately isn't that simple. Suppose we're
multiplying a and b with c bit accuracy.

a' = a * 2^c		b' = b * 2^c	(a' and b' are fixed point numbers)
a' * b'  =  a * 2^c * b * 2^c  =  (a * b) * (2 * 2^c)

As you (hopefully) can see is that you'll have to divide the result by 2^c
after multiplication to get a correct fixed point number. Fortunately that
simply a shift to right by c bits.

With division it is even trickier. Once again we use a and b and an accuracy
of c.

a' = a * 2^c		b' = b * 2^c	(a' and b' are fixed point numbers)
a' / b'  =  (a * 2^c) / (b * 2^c)  =  a / b

Well... There goes our accuracy... Even after shifting it c bytes to the left
again, you will get 3/2=1. (If you want to get those values, you should buy a 
pentium!). How to solve this: instead of changing the accuracy after the
division we will have to do it before the division. so increase the accuracy
of a' with c and you'll get a correct fixed point number. But unfortunately
you don't always have that space, so you'll have to do something like 
increasing the accuracy of a' with c/2 and decreasing the accuracy of b' with
c/2. (it'll give the same result)



 
  ַַ
 Ľ


The trick to creating a lens is quite simple... For each point in the rectangle
the lens fits in, you simply calculate which point you should be seeing there.
To explain this I will now try some of my ASCII-art...

                                  |
                                  |
                                  |
                        _____     |A
                  .---'`  |  `'----.
              ,:'`        |l     /  `':,
            ,'            |     /       ',
  -----------------------------/-r-----------------z= z' = rs-l
          ,|              |   /B          |.
          |'              |  /            `|
          |               | /              |
 _________|_______________|/____rs_________|________z=0
          |                                |

(it should be a circle)	(B is the intersection of the diagonal and z=z')

Here I have taken a sphere that is cut by a plane (the screen) so every ray
that hits the sphere above the screen will change.
r = radius of circle of lens
rs = radius of sphere
l = a value with which you can set the strength of the lens (0<l<rs)

- When does it hit the sphere?

If the point lies within the circle with radius r so  x+y<r else x'=x and
y'=y

- How do I calculate the radius of the sphere ?

    l+r	( you can deduct this from x+y=rs with x=r and y=rs-l )
rs=            ( it's easier than you think )
     2*l

- How do I calculate x' and y' (coordinates of point B) ?

z =  (rs-x-y)                 ( comes from x+y+z=rs )

     z'        rs-l
x'=  * x =  * x
     z          z

     z'        rs-l
y'=  * y =  * y
     z          z

- What do I do with x' and y' ?

I have to excuse myself for my chaotic nature, because I still have to tell
you what the x' and y' are. Well... x' and y' are the texture-coordinates of
the picture you're magnifying. So draw the color at (x',y') at the position
(x,y) and you'll have a point of the lens calculated.

If you don't get it immediately (I can't blame you) try thinking out yourself
what you would do with a few of these thoughts as a starting point... it helped
for me...


(Joey/SD has written some docs about this effect, too, but I can't really
remember where I got those docs, so I can't give you a way of finding them
(well, if you really want to search, I believe I got them from x2ftp.oulu.fi))



    
 Һַַַ
 н ӽ


This one will be a short one, since it is very simple. for each character
you simply calculate the x- and y-position. How? Well... let's say you start
at (xs,ys) and want to go to (xe,ye) in n steps. You calculate the delta-x
and delta-y like this (you should be able to figure this out):

dx=(xe-xs)/n
dy=(ye-ys)/n
x=xs
y=ys

and then you simply draw the character at (x,y) , do x=x+dx; y=y+dy, wait a 
while, draw the point again, add dx and dy again, etc. (You should ofcourse
stop when you reach (xe,ye) (an easy way of checking this is by decrementing
n each time and check if it is zero))

With this routine the fixed point numbers are quite useful, too...




        
 ֶĺڷҷַַ
 ӽĽ


It is sad that I have to write this here, but ah well... here goes:

I assume no responsibility whatsoever for any effect that this file, the
information contained therein or the use thereof has on you, your sanity,
computer, spouse, children, pets or anything else related to you or your
existance. No warranty is provided nor implied with this information.



           
 ַ  ĺַķַַ
   ӽĽӶ
ӽ

I hope this document has helped you (and if not... I hope I didn't bore you).
Contact me if you have any questions concerning these or other techniques. I
would love to be of assistance. (My email address is included in 'CHOSEN.TXT')

Take care and happy coding...

     Ba'alzamon