Program Fractal; {$ApplName Fractal} {$R *.bin} Uses Window, Form, Menu, Rect, Crt, Event, SysEvent, SystemMgr, HSUtils; Const Color = 1; NumIts = 30000; MaxColor = 65000; MaxLines = 4; MaxFractal = 5; DevXMax = 160; DevYMax = 160; MenuAbout = 1001; AlertAbout = 1022; MenuMain = 1000; Type String2 = String[2]; FractalSetRecord = Array [ 1 .. MaxLines ] of Record A, B, C, D, E, F, P : Real; End; WindowRecord = Record X1, Y1, X2, Y2 : Real; End; FractalDataRecord = Record Lines : Byte; Name : String[ 80 ]; W : WindowRecord; FR : FractalSetRecord; End; Var FractalData : FractalDataRecord; Result, PrevY : Integer; WorldX1, WorldY1, WorldX2, WorldY2, WorldXFactor, WorldYFactor : Real; FrcX, FrcY : Real; FractalNum, PrevFractalNum : Byte; CD : Array [ 1 .. MaxFractal ] of FractalDataRecord; WorkRect: RectangleType; Event: EventType; {---------------------------------------------------------------------------} Procedure SetupConstData; Begin CD[1].Lines := 4; CD[1].Name := 'COMET'; CD[1].W.X1 := 0.0; CD[1].W.Y1 := 0.0; CD[1].W.X2 := 18.0; CD[1].W.Y2 := 9.0; CD[1].FR[1].A := 0.0; CD[1].FR[1].B := 0.0; CD[1].FR[1].C := 0.0; CD[1].FR[1].D := 0.0; CD[1].FR[1].E := 1.0; CD[1].FR[1].F := 0.0; CD[1].FR[1].P := 0.01; CD[1].FR[2].A := 0.85; CD[1].FR[2].B := 0.4; CD[1].FR[2].C := -0.04; CD[1].FR[2].D := 0.85; CD[1].FR[2].E := 0.0; CD[1].FR[2].F := 1.6; CD[1].FR[2].P := 0.85; CD[1].FR[3].A := 0.2; CD[1].FR[3].B := -0.26; CD[1].FR[3].C := 0.23; CD[1].FR[3].D := 0.22; CD[1].FR[3].E := 0.0; CD[1].FR[3].F := 1.6; CD[1].FR[3].P := 0.07; CD[1].FR[4].A := -0.15; CD[1].FR[4].B := 0.28; CD[1].FR[4].C := 0.26; CD[1].FR[4].D := 0.24; CD[1].FR[4].E := 0.0; CD[1].FR[4].F := 0.44; CD[1].FR[4].P := 0.07; CD[2].Lines := 4; CD[2].Name := 'FERN'; CD[2].W.X1 := -5.0; CD[2].W.Y1 := 0.0; CD[2].W.X2 := 4.0; CD[2].W.Y2 := 12.0; CD[2].FR[1].A := 0.0; CD[2].FR[1].B := 0.0; CD[2].FR[1].C := 0.0; CD[2].FR[1].D := 0.0; CD[2].FR[1].E := 1.0; CD[2].FR[1].F := 0.0; CD[2].FR[1].P := 0.01; CD[2].FR[2].A := 0.85; CD[2].FR[2].B := -0.03; CD[2].FR[2].C := 0.03; CD[2].FR[2].D := 0.85; CD[2].FR[2].E := 0.0; CD[2].FR[2].F := 1.6; CD[2].FR[2].P := 0.85; CD[2].FR[3].A := 0.2; CD[2].FR[3].B := -0.26; CD[2].FR[3].C := 0.23; CD[2].FR[3].D := 0.22; CD[2].FR[3].E := 0.0; CD[2].FR[3].F := 1.6; CD[2].FR[3].P := 0.07; CD[2].FR[4].A := -0.15; CD[2].FR[4].B := 0.28; CD[2].FR[4].C := 0.26; CD[2].FR[4].D := 0.24; CD[2].FR[4].E := 0.0; CD[2].FR[4].F := 0.44; CD[2].FR[4].P := 0.07; CD[3].Lines := 4; CD[3].Name := 'NEBULA'; CD[3].W.X1 := -0.15; CD[3].W.Y1 := -0.2; CD[3].W.X2 := 0.57; CD[3].W.Y2 := 0.57; CD[3].FR[1].A := 0.1; CD[3].FR[1].B := 0.42; CD[3].FR[1].C := -0.42; CD[3].FR[1].D := 0.5; CD[3].FR[1].E := 0.1; CD[3].FR[1].F := 0.0; CD[3].FR[1].P := 0.1; CD[3].FR[2].A := 0.42; CD[3].FR[2].B := -0.42; CD[3].FR[2].C := 0.42; CD[3].FR[2].D := 0.42; CD[3].FR[2].E := 0.1; CD[3].FR[2].F := 0.2; CD[3].FR[2].P := 0.42; CD[3].FR[3].A := 0.42; CD[3].FR[3].B := 0.42; CD[3].FR[3].C := -0.42; CD[3].FR[3].D := 0.42; CD[3].FR[3].E := 0.2; CD[3].FR[3].F := 0.2; CD[3].FR[3].P := 0.42; CD[3].FR[4].A := 0.1; CD[3].FR[4].B := 0.0; CD[3].FR[4].C := 0.0; CD[3].FR[4].D := 0.1; CD[3].FR[4].E := 0.0; CD[3].FR[4].F := 0.2; CD[3].FR[4].P := 0.06; CD[4].Lines := 4; CD[4].Name := 'SNAILS'; CD[4].W.X1 := -4.5; CD[4].W.Y1 := 0.0; CD[4].W.X2 := 1.5; CD[4].W.Y2 := 4.0; CD[4].FR[1].A := 0.0; CD[4].FR[1].B := 0.0; CD[4].FR[1].C := 0.0; CD[4].FR[1].D := 0.0; CD[4].FR[1].E := 1.0; CD[4].FR[1].F := 0.0; CD[4].FR[1].P := 0.01; CD[4].FR[2].A := 0.74; CD[4].FR[2].B := -0.43; CD[4].FR[2].C := 0.43; CD[4].FR[2].D := 0.74; CD[4].FR[2].E := 0.0; CD[4].FR[2].F := 1.6; CD[4].FR[2].P := 0.85; CD[4].FR[3].A := 0.2; CD[4].FR[3].B := -0.26; CD[4].FR[3].C := 0.23; CD[4].FR[3].D := 0.22; CD[4].FR[3].E := 0.0; CD[4].FR[3].F := 1.6; CD[4].FR[3].P := 0.07; CD[4].FR[4].A := -0.15; CD[4].FR[4].B := 0.28; CD[4].FR[4].C := 0.26; CD[4].FR[4].D := 0.24; CD[4].FR[4].E := 0.0; CD[4].FR[4].F := 0.44; CD[4].FR[4].P := 0.07; CD[5].Lines := 4; CD[5].Name := 'TREE'; CD[5].W.X1 := -0.3; CD[5].W.Y1 := 0.0; CD[5].W.X2 := 0.3; CD[5].W.Y2 := 0.5; CD[5].FR[1].A := 0.0; CD[5].FR[1].B := 0.0; CD[5].FR[1].C := 0.0; CD[5].FR[1].D := 0.5; CD[5].FR[1].E := 0.0; CD[5].FR[1].F := 0.0; CD[5].FR[1].P := 0.05; CD[5].FR[2].A := 0.42; CD[5].FR[2].B := -0.42; CD[5].FR[2].C := 0.42; CD[5].FR[2].D := 0.42; CD[5].FR[2].E := 0.0; CD[5].FR[2].F := 0.2; CD[5].FR[2].P := 0.4; CD[5].FR[3].A := 0.42; CD[5].FR[3].B := 0.42; CD[5].FR[3].C := -0.42; CD[5].FR[3].D := 0.42; CD[5].FR[3].E := 0.0; CD[5].FR[3].F := 0.2; CD[5].FR[3].P := 0.4; CD[5].FR[4].A := 0.1; CD[5].FR[4].B := 0.0; CD[5].FR[4].C := 0.0; CD[5].FR[4].D := 0.1; CD[5].FR[4].E := 0.0; CD[5].FR[4].F := 0.2; CD[5].FR[4].P := 0.15; End; {---------------------------------------------------------------------------} Procedure SetWorld( InX1, InY1, InX2, InY2 : Real ); Begin WorldX1 := InX1; WorldY1 := InY1; WorldX2 := InX2; WorldY2 := InY2; WorldXFactor := DevXMax / ( WorldX2 - WorldX1 ); WorldYFactor := DevYMax / ( WorldY2 - WorldY1 ); End; {---------------------------------------------------------------------------} Procedure Plot( X, Y, C : LongInt ); Begin Result := WinSetForeColor(C); WinDrawPixel(X,Y); End; {----------------------------------------------------------------} Function GetDot( X, Y : LongInt ) : LongInt; Begin GetDot := WinGetPixel(X,Y); End; {----------------------------------------------------------------} Procedure SetDot( X, Y : Real ); Var Color : LongInt; Begin If ( X >= WorldX1 ) and ( X <= WorldX2 ) and ( Y >= WorldY1 ) and ( Y <= WorldY2 ) Then Begin X := ( X - WorldX1 ) * WorldXFactor; Y := ( DevYMax - 1 ) - ( Y - WorldY1 ) * WorldYFactor; Color := GetDot( Trunc( X ), Trunc( Y ) ); If Color < MaxColor Then Color := Trunc( (Color + 1) * 1.5 ); Plot( Trunc( X ), Trunc( Y ), Color ) End; End; {---------------------------------------------------------------------------} Procedure Iterate; Var Delta : Byte; R, Prob, NewX, NewY : Real; Begin With FractalData do Begin R := Random; Prob := FR[ 1 ].P; Delta := 1; While ( R > Prob ) and ( Delta < Lines ) do Begin Inc( Delta ); Prob := Prob + FR[ Delta ].P; End; With FR[ Delta ] do Begin NewX := A * FrcX + B * FrcY + E; NewY := C * FrcX + D * FrcY + F; End; FrcX := NewX; FrcY := NewY; SetDot( FrcX, FrcY ); End; End; {---------------------------------------------------------------------------} Procedure Generate; Var BurstIt : LongInt; ItLoop : LongInt; BResult : Boolean; Const BurstSize = 100; Begin FrcX := 0.0; FrcY := 0.0; SetWorld( FractalData.W.X1, FractalData.W.Y1, FractalData.W.X2, FractalData.W.Y2 ); ItLoop := 1; While ( ItLoop <= NumIts ) do Begin For BurstIt := 1 to BurstSize do Iterate; EvtGetEvent(Event, 5); if (Event.eType = 21) Then Result := FrmAlert(AlertAbout) Else BResult := SysHandleEvent(Event); If (Event.eType = appStopEvent) Then Exit; ItLoop := ItLoop + BurstSize; End; End; {---------------------------------------------------------------------------} Resource (ResTAIN,1000,'Fractal'); (Restver,1000,'1.0'); Begin Randomize; RctSetRectangle(WorkRect, 0, 0, 160, 160); SetupConstData; FractalNum := 0; While True Do Begin PrevFractalNum := FractalNum; Repeat FractalNum := Trunc(1 + ( MaxFractal * Random)); Until (FractalNum <> PrevFractalNum); WinEraseRectangle(WorkRect, 0); FractalData := CD[ FractalNum ]; GotoXY(1,1); WriteLn('Fractals by Andrew@Bedno.com'); GotoXY(16,16); Write(FractalData.Name); Generate; If (Event.eType=appStopEvent) Then Exit; End; End.