maxc1087@ucselx.sdsu.edu (James Hensley) (09/22/89)
here are a couple of pascal fractal progs. one implements the random iteration algorithm and is quite fast, the other a slow escape time julia set generator. (run it overnight) - I converted some IBM turbo basic code I found. (see comments.) runs on my 128k enhanced //e, but I think any ][ that can run apple pascal 1.2. ----------------- * cut here * ------------------ program RandomItFrac(input, output, VarFile); { Author : James Hensley } { Program : RandomItFrac } { Purpose : create fractals, using IFS } { algorithm from Barnsley, } { Fractals EveryWhere, Academic } { Press, 1988, Program 9.8.1 } { allow reading of variables } { from a file, keyboard, or } { default to a fractal tree. } { Machine : Apple //e, 128k } { Language: UCSD Pascal } { OpSys : Apple Pascal 1.2 } { Comments: this was converted from a BASIC } { program (ick!) } uses TurtleGraphics, AppleStuff; const MaxBounds = 4; MaxX = 279; MaxY = 191; var Debug : boolean; Ch : char; A, D, B, C, F : array[1..MaxBounds] of real; E, P : array [1..MaxBounds] of integer; X, Y, NewX, NewY : real; Loop, NumIts, N, K, R, W, XScale, YScale, XAdd, YAdd : integer; Err : boolean; CommentLine, FileName : string; VarFile : text; procedure Plot(X, Y: real); var Xt, Yt : integer; Dot : boolean; begin Xt := XAdd + trunc(XScale * X); Yt := YAdd + trunc(XScale * Y); if Debug then begin writeln('Plot, x=', X, ' y=', Y); writeln('Plot, xt=', Xt, ' yt=', Yt); end; { if Debug } if (Xt <= MaxX) and (Yt <= MaxY) then DrawBlock(Dot, 1, 0, 0, 1, 1, Xt, Yt, 15) else begin chartype(6); pencolor(black); moveto(50, 50); pencolor(blue); wstring('Point out of bounds'); end; end; { Plot } function Rand(Low, High:integer; var Error:boolean):integer; var Mx, C, D : integer; begin Rand := 0; Error := true; if Low > High then exit(Rand); { error in params } if Low <= 0 then if High > MaxInt + Low then exit(Rand); Error := false; if Low = High then Rand := Low else begin C := High - Low + 1; Mx := (MaxInt - High + Low) div C; Mx := Mx * (High - Low) + (Mx - 1); repeat D := random until D <= Mx; Rand := Low + D mod C; end; { else } end; { rand } procedure InitArrays; begin A[1] := 0; A[2] := 0.42; A[3] := 0.42; A[4] := 0.1; B[1] := 0; B[2] := -0.42; B[3] := 0.42; B[4] := 0; C[1] := 0; C[2] := 0.42; C[3] := -0.42; C[4] := 0; D[1] := 0.5; D[2] := 0.42; D[3] := 0.42; D[4] := 0.1; E[1] := 0; E[2] := 0; E[3] := 0; E[4] := 0; F[1] := 0; F[2] := 0.2; F[3] := 0.2; F[4] := 0.2; P[1] := 5; P[2] := 40; P[3] := 40; P[4] := 15; NumIts := 1000; XScale := 200; YScale := 100; XAdd := 100; Yadd := 75; end; { InitArrays } procedure GetChoices; procedure DoFile; begin write('FileName>'); readln(FileName); reset(VarFile, FileName); readln(VarFile, CommentLine); while (CommentLine[1] = '!') do begin readln(VarFile, CommentLine); writeln(CommentLine); end; readln(VarFile, W); writeln('W=', W); readln(VarFile, NumIts, XScale, YScale, XAdd, YAdd); writeln(NumIts, XScale, YScale, XAdd, YAdd); for Loop := 1 to W do begin readln(VarFile, A[Loop], B[Loop], C[Loop], D[Loop], E[Loop], F[Loop], P[Loop]); writeln(A[Loop], B[Loop], C[Loop], D[Loop], E[Loop], F[Loop], P[Loop]); end; end; { DoFile } procedure DoKb; begin write('Number of iterations'); readln(NumIts); write('X scale'); readln(XScale); write('Y scale'); readln(YScale); write('X adder'); readln(XAdd); write('Y adder'); readln(YAdd); repeat write('W='); read(W); if (W > MaxBounds) or (trunc(W) <> W) then write('Maximum=', MaxBounds:2); until W <= MaxBounds; writeln; for Loop := 1 to W do begin write('A[', W:2, ']>'); readln(A[W]); write('B[', W:2, ']>'); readln(B[W]); write('C[', W:2, ']>'); readln(C[W]); write('D[', W:2, ']>'); readln(D[W]); write('E[', W:2, ']>'); readln(E[W]); write('F[', W:2, ']>'); readln(F[W]); write('P[', W:2, ']>'); readln(P[W]); end; { for Loop } end; { DoKb } begin { GetChoices } InitArrays; { default to tree. } write('Read vars from File or Keyboard (F/K)>'); read(Ch); writeln; if Ch in ['f', 'F'] then DoFile; if Ch in ['k', 'K'] then DoKb; end; { GetChoices } begin { main } GetChoices; randomize; initTurtle; pencolor(White); page(output); Debug := false; { may be set at any time during execution. } X := 0; Y := 0; for N := 1 to NumIts do begin R := rand(0, 100, Err); K := 1; { check probability } if R > P[1] then K := 2; if R > P[1] + P[2] then K := 3; if R > P[1] + P[2] + P[3] then K := 4; NewX := A[K]*X + B[K]*Y + E[K]; NewY := C[K]*X + D[K]*Y + F[K]; X := NewX; Y := NewY; if N > 10 then Plot(X,Y); if keypress then begin read(Ch); if Ch in ['d', 'D'] then begin Debug := not(Debug); pencolor(black); moveto(0,0); pencolor(blue); wstring('debug '); if Debug then wstring('on ') else wstring('off'); pencolor(white); end; { if ch in [d,D] } if Ch in [Chr(27), 'q', 'Q'] then exit(RandomItFrac) else if not (Ch in ['d', 'D']) then begin textmode; repeat page(output); write('"q" to quit, "c" to continue>'); read(Ch); writeln; if Ch in ['q', 'Q'] then begin page(output); writeln('leaving RandomIteration.'); writeln('have a fractal day'); exit(RandomItFrac); { later..... } end; until (Ch in ['c', 'C']); grafmode; end; { else begin } end; { if keypress } end; { for N } textmode; page(output); writeln('hit a key to exit, "v" to view picture.'); read(Ch); if Ch in ['v', 'V'] then begin grafmode; read(keyboard, ch); textmode; end; { if } page(output); end. { -- these files are used by the Random Iteration program. -- } { -- save them under the filename specified and enter at prompt. } { -- leave the blank line after the comments. } { ------- snip here ------- } ! File:Fern.Text. - data for a fern picture. ! Date:4-Sep-89 ! Format: W = number of rows in array ! NumIts, XScale, YScale, XAdd, YAdd ! A[W],B[W],C[W],D[W],E[W],F[W],P[W] ! for W rows. ! A B C D E F P 4 2000 14 7 100 50 0 0 0 0.16 0 0 1 0.85 0.04 -0.04 0.85 0 1.6 85 0.2 -0.26 0.23 0.22 0 1.6 7 -0.15 0.28 0.26 0.24 0 0.44 7 { ------- snip here ------ } ! File:Tree.Text - data for a tree picture. ! Date:4-Sep-89 ! Format: W = number of rows in array ! NumIts, XScale, YScale, XAdd, YAdd ! A[W],B[W],C[W],D[W],E[W],F[W],P[W] ! for W rows. ! A B C D E F P 4 2000 250 124 150 50 0 0 0 0.5 0 0 5 0.42 -0.42 0.42 0.42 0 0.2 40 0.42 0.42 -0.42 0.42 0 0.2 40 -0.1 0 0 0 0 0.2 15 { ------ snip here ------- } ! File: Tri.Text. - data for a triangle picture. ! Date:4-Sep-89 ! Format: W = number of rows in array ! NumIts, XScale, YScale, XAdd, YAdd ! A[W],B[W],C[W],D[W],E[W],F[W],P[W] ! for W rows. ! A B C D E F P 3 4000 1 1 100 50 0.5 0 0 0.5 1 1 33 0.5 0 0 0.5 1 50 33 0.5 0 0 0.5 50 50 34 { ----- snip here ------ } ! File:Square.Text - data for a square picture ! Date:4-Sep-89 ! Format: W = number of rows in array ! NumIts, XScale, YScale, XAdd, YAdd ! A[W],B[W],C[W],D[W],E[W],F[W],P[W] ! for W rows. ! A B C D E F P 4 2000 1 1 10 5 0.5 0 0 0.5 1 1 25 0.5 0 0 0.5 50 1 25 0.5 0 0 0.5 1 50 25 0.5 0 0 0.5 50 50 25 {-------------------- *snip here* --------------------} program EscapeTime(input, output, VarFile); { Author : James Hensley } { Language: UCSD Pascal } { Machine : Apple //e, 128k } { OpSys : Apple Pascal 1.2 } { Purpose : implement julia set Escape time algorithm } { as found as in Barnsley: Fractals Everywhere, } { Academic press, 1989, program 7.1.1 } { Use colors White, Orange, Violet, Blue, Green. } { Was converted from a nasty BASIC pgm (IBM, yet!) } (*$R-*) { disable compiler range checking } uses TurtleGraphics, AppleStuff; const MaxX = 279; { screen dimensions } MaxY = 191; var Ch : char; A, {= -2;} B, {= -2;} C, {= 2;} D, {= 2;} R, {= 16;} { 200 } NumIts : integer; {= 20;} P, Q : 1..512; Color : integer; K, L, X, NewX, Y, NewY : real; PenArray : array[1..5] of ScreenColor; VarFile : text; procedure Plot(X, Y: integer; Color:integer); var Dot:boolean; begin if X <= MaxX then { bounds check } if Y <= MaxY then begin PenColor(None); MoveTo(X,Y); PenColor(PenArray[Color]); MoveTo(X,Y); { DrawBlock(Dot, 1, 0, 0, 1, 1, X, Y, 3); } end; { if vars in bounds } end; { Plot } begin writeln('Read vars from file or Keyboard? (F/K)'); readln(Ch); if Ch in ['f', 'F'] then begin reset(VarFile, 'EscDat.Text'); readln(VarFile, A, B, C, D, R, NumIts); writeln('A=', A); writeln('B=', B); writeln('C=', C); writeln('D=', D); writeln('R=', R); close(VarFile); end else if Ch in ['K', 'k'] then begin { get vars from user } write('NumIts>'); readln(NumIts); write('A>'); readln(A); write('B>'); readln(C); write('D>'); readln(D); write('R>'); readln(R); end { else read from keyboard } else begin { use internal var values. } NumIts := 20; A := -2; B := -2; C := 2; D := 2; R := 16; end; { if } PenArray[1] := White; PenArray[2] := Green; PenArray[3] := Violet; PenArray[4] := Orange; PenArray[5] := Blue; InitTurtle; for P := 1 to MaxX do for Q := 1 to MaxY do begin X := A + (C-A) * P/MaxX; Y := B + (D-B) * Q/MaxY; for Color := 1 to NumIts do begin if Y > 0.5 then begin X := 2 * X; Y := 2 * Y - 1; end else if X > 0.5 then begin X := 2 * X - 1; Y := 2 * Y; end else begin X := 2 * X; Y := 2 * Y; end; if X*X + Y*Y > R then begin Plot(P, Q, Color mod 4 + 1); Color := NumIts; end; { if X*X+Y*Y } if keypress then begin read(keyboard, Ch); if (Ch = 'Q') or (Ch = 'q') or (Ch = chr(27)) then begin writeln('Escape Time Escaped.'); exit(EscapeTime); end; { if } end; { if keypress } end; { for Color } end; { for Q } read(Ch); end.