| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262 |
- Unit Lsystems;
- InterFace
- Uses Graph;
- const
- MaxStack = 100;
- MaxBuf = 10000;
- type
- PLsys = ^TLsys;
- PS = ^String;
- TLsys = record
- Axiom : string;
- Comment : string;
- Turns : integer;
- RulesTable : array [0..255] of PS;
- end;
- Tpos = record
- x, y, a : real;
- end;
- Function CreateLsys(aAxiom, aComment : string; aTurns : integer):PLsys;
- Procedure AddRule(var aFrac : PLsys; aCh : char; aRule:string);
- Procedure DestroyLsys(var aFrac : PLsys);
- Function Calculate(var aFrac:PLsys; aStage : integer):string;
- Function Advance(var aFrac:PLsys; PrevName : string):string;
- Procedure DrawLsys(fName : string; var aFrac : PLsys);
- Implementation
- Function CreateLsys;
- var RET:PLsys;i:byte;
- begin
- New(RET);
- RET^.Axiom := aAxiom;
- RET^.Comment := aComment;
- RET^.Turns := aTurns;
- for i:=0 to 255 do RET^.RulesTable[i]:=nil;
- CreateLsys := RET;
- end;{CreateLsys}
- {--------------------------------------------}
- Procedure AddRule;
- begin
- if aFrac = nil then begin writeln('AddRule Error: Fractal undefined'); halt(255);end;
- if aFrac^.RulesTable[Ord(aCh)] <> nil then Dispose(aFrac^.RulesTable[Ord(aCh)]);
- New(aFrac^.RulesTable[Ord(aCh)]);
- aFrac^.RulesTable[Ord(aCh)]^ := aRule;
- end;{AddRule}
- {--------------------------------------------}
- Function Calculate;
- var
- A : FILE;
- CH : char;
- N1 : string;
- I : integer;
- begin
- n1:='1.!!!';
- if odd(aStage) then Calculate := '2.!!!'
- else Calculate := '1.!!!';
- Assign(A,'1.!!!');
- Rewrite(A,1);
- BlockWrite(A,Ptr(Seg(aFrac^.Axiom),Ofs(aFrac^.Axiom)+1)^,Length(aFrac^.Axiom));
- Close(A);
- For i := 1 to aStage do
- begin
- N1:=Advance(aFrac,N1);
- end;
- end;{Calculate}
- {--------------------------------------------}
- Function Advance;
- type PFILE=^FILE;
- var
- A,B : PFILE;
- Out : string;
- CH : char;
- I : integer;
- begin
- New(A);NEW(B);
- if PrevName = '1.!!!' then out:='2.!!!'
- else out:='1.!!!';
- Advance := out;
- Assign(A^,PrevName);
- Assign(B^,Out);
- Reset(A^,1);
- Rewrite(B^,1);
- repeat
- BlockRead(A^,CH,1);
- if aFrac^.RulesTable[Ord(ch)] <> nil then BlockWrite(B^,Ptr(Seg(aFrac^.RulesTable[Ord(ch)]^),
- Ofs(aFrac^.RulesTable[Ord(ch)]^)+1)^,Length(aFrac^.RulesTable[Ord(ch)]^))
- else BlockWrite(B^,Ch,1);
- until EOF(A^);
- Close(A^);
- Close(B^);
- Erase(A^);
- Dispose(A);Dispose(B);
- end;{Advance}
- {--------------------------------------------}
- Procedure DestroyLsys;
- var i:byte;
- begin
- for i:=0 to 255 do if aFrac^.RulesTable[i] <> nil then
- Dispose(aFrac^.RulesTable[i]);
- Dispose(aFrac);
- end;{DestroyLsys}
- {-------------------------------------------}
- Procedure DrawLsys;
- type TBuf = array [1..MaxBuf] of char;
- Var
- Step : real;
- StackPos : integer;
- Stack : array [1..MaxStack] of Tpos;
- Buffer : ^TBuf;
- BufPos,NumRead:1..MaxBuf;
- C : Tpos;
- Ip : FILE;
- dx, dy,cx,cy : real;
- da : real;
- MaxX,MinX,MaxY,MinY : real;
- begin
- Step := 100.0;
- da := 2*PI/aFrac^.Turns;
- New(Buffer);
- Assign(ip,fName);
- Reset(ip,1);
- BlockRead(ip,Buffer^,MaxBuf,NumRead);
- BufPos:=1;
- StackPos:=1;
- dx:=step;dy:=0;C.x:=0;c.y:=0;c.a:=0;
- MaxX:=0;MaxY:=0;MinX:=0;MinY:=0;
- repeat
- case Buffer^[BufPos] of
- 'F': begin
- c.x := c.x + dx;
- c.y := c.y + dy;
- If C.X > MaxX then MaxX := c.x;
- If C.X < MinX then MinX := c.x;
- If C.Y > MaxY then MaxY := c.y;
- If C.Y < MinY then MinY := c.y;
- end;
- '+': begin
- c.a := c.a - da;
- if c.a > 2*PI then c.a:=c.a-2*Pi;
- if c.a < 0 then c.a:=c.a+2*Pi;
- dx := cos(c.a)*Step;
- dy := sin(c.a)*Step;
- end;
- '-': begin
- c.a := c.a + da;
- if c.a > 2*PI then c.a:=c.a-2*Pi;
- if c.a < 0 then c.a:=c.a+2*Pi;
- dx := cos(c.a)*Step;
- dy := sin(c.a)*Step;
- end;
- '[': begin
- If StackPos > MaxStack then
- begin
- CloseGraph;
- WriteLN('Stack overflow');
- Halt(210);
- end;
- Stack[StackPos] := C;
- Inc(StackPos);
- end;
- ']': begin
- If StackPos = 1 then
- begin
- CloseGraph;
- WriteLN('Stack error');
- Halt(200);
- end;
- Dec(StackPos);
- C:=Stack[StackPos];
- dx := cos(c.a)*Step;
- dy := sin(c.a)*Step;
- end;
- end;
- Inc(BufPos);
- if BufPos = NumRead+1 then
- begin
- BlockRead(ip,Buffer^,MaxBuf,NumRead);
- BufPos:=1;
- end;
- if NumRead = 0 then break;
- until false;
- if (MaxY=MinY) and (MaxX=MaxY) then
- begin
- Exit;
- end;
- if (MaxX-MinX)/(MaxY-MinY) > 4/3 then
- Step := 61300/(MaxX-MinX)
- else
- step := 46000/(MaxY-MinY);
- cx := (MaxX+MinX)*step/200;
- cy := (MaxY+MinY)*step/200;
- Seek(ip,0);
- BlockRead(ip,Buffer^,MaxBuf,NumRead);
- BufPos:=1;
- StackPos:=1;
- dx:=step;dy:=0;C.x:=0;c.y:=0;c.a:=0;
- OutTextXY(10,5,aFrac^.Comment);
- repeat
- case Buffer^[BufPos] of
- 'F': begin
- moveto(round(320-cx+c.x),round(240+cy-c.y));
- c.x := c.x + dx;c.y := c.y + dy;
- LineTo(round(320-cx+c.x),round(240+cy-c.y))
- end;
- '+': begin
- c.a := c.a - da;
- if c.a > 2*PI then c.a:=c.a-2*Pi;
- if c.a < 0 then c.a:=c.a+2*Pi;
- dx := cos(c.a)*Step;
- dy := sin(c.a)*Step;
- end;
- '-': begin
- c.a := c.a + da;
- if c.a > 2*PI then c.a:=c.a-2*Pi;
- if c.a < 0 then c.a:=c.a+2*Pi;
- dx := cos(c.a)*Step;
- dy := sin(c.a)*Step;
- end;
- '[': begin
- If StackPos > MaxStack then
- begin
- WriteLN('Stack overflow');
- Halt(210);
- end;
- Stack[StackPos] := C;
- Inc(StackPos);
- end;
- ']': begin
- If StackPos = 1 then
- begin
- WriteLN('Stack error');
- Halt(200);
- end;
- Dec(StackPos);
- C:=Stack[StackPos];
- dx := cos(c.a)*Step;
- dy := sin(c.a)*Step;
- end;
- end;
- Inc(BufPos);
- if BufPos = NumRead+1 then
- begin
- BlockRead(ip,Buffer^,MaxBuf,NumRead);
- BufPos:=1;
- end;
- if NumRead = 0 then break;
- until false;
- close(ip);
- Dispose(Buffer);
- end; {DrawLsys}
- {--------------------------------------------}
- END.
|