Code:
unit MandelCalc;
interface
uses
Windows, Classes, Graphics, SysUtils;
type
TMandelCalc = class(TThread)
private
{ Private declarations }
X, Y, Len, Colour, Focus, XStep : integer;
DrawRect : TRect;
ColPoints : Array [0..1023] of integer;
procedure Synchro;
protected
procedure Execute; override;
public
{ Public declarations }
constructor Create(InitR, InitI, Size, SeedR, SeedI : Extended;
MaxLen, MaxIterate, ParmStep : integer;
FracJulia, dspAttract, dspMono : boolean);
end;
implementation
uses
MandelScreen, MandelOptions;
constructor TMandelCalc.Create(InitR, InitI, Size, SeedR, SeedI : Extended;
MaxLen, MaxIterate, ParmStep : integer;
FracJulia, dspAttract, dspMono : boolean);
begin
XStep := ParmStep;
FreeOnTerminate := True;
Priority := tpTimeCritical;
inherited Create(False);
end;
procedure TMandelCalc.Execute;
var
R, I, Step : Extended;
CountX, CountY : integer;
function Calculate(R0, I0: Extended):integer;
const
RequiredRep = 1;
var
Iterate : integer;
R1, I1, R2, I2 : Extended;
LastR, LastI : Extended;
CheckEvery, Periodicity, LastPeriod, NumRep : integer;
procedure CheckAttractor;
begin
if (abs(R1 - LastR) < Step) and (abs(I1 - LastI) < Step) then
begin
if LastPeriod = Periodicity then
begin
NumRep := NumRep + 1;
if NumRep = RequiredRep then
begin
if dspAttract then
Colour := Iterate;
Iterate := MaxIterate + 1;
end
end
else
begin
LastPeriod := Periodicity;
Periodicity := 1;
end
end
else
begin
Periodicity := Periodicity + 1;
if Periodicity >= CheckEvery then
begin
CheckEvery := CheckEvery * 2;
Periodicity := 1;
LastR := R1;
LastI := I1;
NumRep := 0;
end;
end;
end;
begin
Iterate := 1;
R1 := R0;
I1 := I0;
if FracJulia then
begin
R0 := SeedR;
I0 := SeedI;
end;
LastR := 0;
LastI := 0;
NumRep := 0;
Periodicity := 1;
LastPeriod := 2;
CheckEvery := 2;
Colour := 0;
while (sqr(R1) + sqr(I1) < 4) and (Iterate <= MaxIterate) do
begin
Iterate := Iterate + 1;
R2 := sqr(R1) - sqr(I1) + R0;
I2 := 2 * R1 * I1 + I0;
R1 := R2;
I1 := I2;
{if (not FracJulia) or dspAttract then} CheckAttractor;
end;
if Iterate > MaxIterate then
Iterate := 0;
if (Colour = 0) and not dspAttract then
Colour := Iterate;
if Colour = 0 then
Result := OptionsForm.ColourSet
else
begin
if dspMono then
Result := (Colour mod 2) * $FFFFFF
else
Result := OptionsForm.CalcColour(Colour);
end;
end;
begin
Focus := MaxLen - 1;
{ Focus := 1; }
repeat
Len := MaxLen div (Focus + 1);
Step := Size / (Focus + 1);
CountX := Focus div 2;
while (CountX <= Focus) and (CountX >= 0) do
begin
X := CountX * Len;
R := InitR + (CountX * Step);
for CountY := 0 to Focus do
begin
colPoints[CountY] := -1;
{ if ((CountX mod 2) + (CountY mod 2) <> 0)
or ((CountX = 0) and (CountY = 0)) then }
begin
Y := CountY * Len;
I := InitI - (CountY * Step);
Colour := Calculate(R, I);
ColPoints[CountY] := Colour;
end;
end;
if MandelScreen.StopThread then
exit;
synchronize(Synchro);
CountX := CountX + XStep;
end;
Focus := (Focus * 2) + 1;
until Focus > MaxLen;
end;
procedure TMandelCalc.Synchro;
var
LoopY : integer;
begin
for LoopY := 0 to Focus do
begin
if ColPoints[LoopY] <> -1 then
begin
Y := LoopY * Len;
if Len > 1 then
begin
DrawRect := Rect(X, Y, X + Len, Y + Len);
with MandelScreen.Bitmap.Canvas do
begin
Brush.Color := ColPoints[LoopY];
FillRect(DrawRect);
end;
end
else
begin
MandelScreen.Bitmap.Canvas.Pixels[X,Y] := ColPoints[LoopY];
end;
end;
end;
DrawRect := Rect(X, 0, X + Len, MaxLen);
frmMandelbrot.imgMandel.Canvas.CopyRect(DrawRect,MandelScreen.Bitmap.Canvas,DrawRect);
end;
end.
Bookmarks