program mset;     {creates a zooming-in animation of the M set. Almost
                  the same as the 'mset' program. It will create ten frames
                  of the animation.}
uses crt, graph;

var     xcorner, y2corner, x2corner, ycorner, count2: real;
        xsize, ysize, k, i, xgap, ygap, max, counter, Size: integer;
        ca, cb, za1, za2, zb, x, y: real;
        gd, gm: integer;
        count, del, del2: word;
        A, B, C, D, E, F, G, H, J, L: POINTER;
        xcor1, xcor2, x2cor1, x2cor2, ycor1, ycor2, y2cor1, y2cor2, x1, x2 :real;


procedure iterate;
begin
count := 0;
za1 := 0;
za2 := 0;
zb := 0;
while 1 = 1 do
begin
za1 := za2;
za2 := (za1 * za1 - zb * zb) + ca;
zb := za1 * zb * 2 + cb;
iF za2 * za2 + zb * zb > 4 THEN EXIT;
count := count + 1;
if count > max then EXIT;
end;

END;





procedure main;
begin
counter := 1;
clrscr;
write(counter, counter);
gd := Detect;
InitGraph(gd, gm, 'd:\tp\bgi');



xsize := 200;
ysize := 200;
xgap := 0;
ygap := 0;
max := 500;

x1 :=0.2;           {there was not enough memory on the computer to store
                     all the frames of the animation, so we had to split
                     it into five stages. x1 = 1 for the first part, and
                     decrease by 0.2 for each stage, concluding with
                     x1 = 0.2 for the last part.}
x2 := x1;

xcor1 := -2.2;       {starting co-ords}
y2cor1 := 1.4;
x2cor1 := 0.6;
ycor1 := -1.4;


xcor2 :=  -0.101665;
y2cor2 := -0.951285;
x2cor2 := -0.10156;
ycor2 :=  -0.95139;



Size := ImageSize(0, ysize, xsize, 0);
GetMem(A,Size);
Getmem(B,Size);
Getmem(C,Size);
Getmem(D,Size);
Getmem(E,Size);

Getmem(F,Size);
Getmem(G,Size);
Getmem(H,Size);
Getmem(J,Size);
Getmem(L,Size);

while x1 > x2-0.2 do
begin
x := sqr(sqr(sqr(x1)));       {We had to make the change between frames
                              exponential otherwise it would have been
                              too fast zooming in}
xcorner := (xcor1 - xcor2) * x + xcor2;
y2corner := (y2cor1 - y2cor2) * x + y2cor2;
x2corner := (x2cor1 - x2cor2) * x + x2cor2;
ycorner := (ycor1 - ycor2) * x + ycor2;
FOR k := ysize downTO 1 do
begin
FOR i := 1 TO xsize do
begin
ca := (i / xsize) * (x2corner - xcorner) + xcorner;
cb := (k / ysize) * (y2corner - ycorner) + ycorner;
iterate;
setcolor(count);
if count > max then setcolor(black) else
begin
count2 := count / ((max - 150)/ 16);
                              {This is different to set.pas. We have made
                              the colours dependent on the 'max' value
                              entered.}
if count > max - 150 then count2 := 15;
if count2 < 1 then setcolor(1) else
begin
count := round(count2);
setcolor(count);
end;
end;
LINE (xgap + i, ygap + ysize - k, xgap + i, ygap + ysize - k);
end;
end;
if counter = 1 then getimage(0,ysize,xsize,0, A^);
if counter = 2 then getimage(0,ysize,xsize,0, B^);
if counter = 3 then getimage(0,ysize,xsize,0, C^);
if counter = 4 then getimage(0,ysize,xsize,0, D^);
if counter = 5 then getimage(0,ysize,xsize,0, E^);
if counter = 6 then getimage(0,ysize,xsize,0, F^);
if counter = 7 then getimage(0,ysize,xsize,0, G^);
if counter = 8 then getimage(0,ysize,xsize,0, H^);
if counter = 9 then getimage(0,ysize,xsize,0, J^);
if counter = 10 then getimage(0,ysize,xsize,0, L^);
counter := counter + 1;
x1 := x1 - 0.02;
CLEARDEVicE;
end;

repeat
cleardevice;

putimage(0,0, A^, NormalPut);
delay(del);
putimage(0,0, B^, NormalPut);
delay(del);
putimage(0,0, C^, NormalPut);
delay(del);
putimage(0,0, D^, NormalPut);
delay(del);
putimage(0,0, E^, NormalPut);
delay(del);
putimage(0,0, F^, NormalPut);
delay(del);
putimage(0,0, G^, NormalPut);
delay(del);
putimage(0,0, H^, NormalPut);
delay(del);
putimage(0,0, J^, NormalPut);
delay(del);
putimage(0,0, L^, NormalPut);
delay(del);
readln(del);
if del = 0 then del := del2;    {When the program is running, at the end
                                type 1 to exit, 0 to repeat the animation
                                with the same delay between frames, or type
                                another number for a different delay.}
until del = 1;
END;


begin
main;
end.