home *** CD-ROM | disk | FTP | other *** search
Wrap
unit Mandelbrot; interface uses Windows, SysUtils, Messages, Classes, Graphics, Controls, Forms, Dialogs, Graphic, Colors, Math, Complex;//ComplexMathLibrary; //Complex; type TMandelState = (msRun, msPause, msStopped, msDone, msNone, msSaved, msStopping); TThreadBounded = class; TMandelPtr= ^TMandelSet; TMandelSet = record FVersion : string[32]; FImageFile : string[255]; FName : string[32]; FCentReal : string[32]; FCentImag : string[32]; FMagnitud : string[32]; FAlgo : string[16]; FIter : string[16]; FOffset : string[16]; // was FIfGreater FWidth : string[16]; FHeight : string[16]; FAspectR : string[16]; FPriority : string[16]; FJulia : boolean; FColors : string[24]; FBailout : string[32]; FRealPert : string[32]; FImagPert : string[32]; FApplyC : string[16]; FFormula : string[16]; FComments : string[255]; FState : TMandelState; FTime : string[32];// was FCrono FCrono : string[16]; // was FSteps FReserved : string[16]; end; TFormulaF = (ffQuad, ffCube, ffForth, ffEight, ffZed, ffSqSingle, ffLambda, ffZedC, ffSin, ffSinTan, ffSpider, ffMagnetism, ffDoubleTail); TApplyC = ( Iter, Vepstas, Real, Imag, Sum, IntMod, IntRadiant, Prod, SumI, BioM, Radiant, IterRad ); TMandAlgo = ( maInterp256, maInterp8, maInterpEven, maPlain, maBounded, maBoundedMP, maDraft, maOrbits ); TFilterKind = ( fkNone, fkEdge, fkBumper, fkHeight, fkNoise, fkLines, fkCristals, fkEqColors, fkColorBumper, fkUnsharpMask, fkAverage ); TMandParameters = record // init given parameters FCentReal: Extended; FCentImag: Extended; FMagnitud: Extended; FIter: Extended; FWidth: Integer; FHeight: Integer; FAspectR: Extended; FJulia: Boolean; FBailout: Integer; FRealPert: Extended; FImagPert: Extended; FApplyC: TApplyC; FFormula: TFormulaf; FAlgo: TMandAlgo; // init calculated parameters FMaxIterVal : Extended; // max value. Usually equal to FIter but it can be different in some formulas FCQuad: Boolean; FIncI: Extended; FIncR: Extended; FMinCR: Extended; FMinCI: Extended; FExtraPar1: Extended; //was ValItr FExtraPar2: Extended; end; TProgrEvent = procedure ( Sender: TObject; var Continue: boolean; Progress: Extended = -1 ) of object; TMandelInfo = record FInsideCount: Cardinal; FMin: Extended; FMax: Extended; // excluded points inside the Set end; TMandelbrot = class private Bmp: TBitmap; MandelSet: TMandelSet; FProdVers: string; values: array of Extended; FOnProgress: TProgrEvent; FTimer: Cardinal; FInfo: TMandelInfo; FFilter: TFilterKind; FPrevFilter: TFilterKind; FMndcount: Cardinal; FLastTime: Cardinal; function Getvalue( x, y : integer ): Extended; procedure Orbit; function BorderEqual( ARect: TRect ): extended; procedure CalculateBorders( ARect: TRect ); procedure Enclose( Rect: TRect; BordersDone: boolean); function BordersEqual( x, y, step: integer; Adiacents, Diagonals: boolean; var val: extended ): boolean; procedure Draft( Step: integer ); procedure Interpolate( Step: integer ); procedure Pass( IsOdd: boolean; Step: integer; Interpolate: boolean ); procedure FillVal( ARect: TRect; AValue: Extended; ValOnly: boolean ); procedure Fill(ARect: TRect; AValue: Extended ); procedure TraceBar( Horizontal: boolean; ARect: Trect; var r1, r2: TRect ); procedure DrawAll( step: integer ); procedure SetOnProgress(const Value: TProgrEvent); procedure SetTimer(const Value: Cardinal); procedure CutBorders(var Rect: TRect); function FilteredValuesToCol( Filter: TFilterKind; Val, ValUp, ValDown, ValLeft, ValRight: extended ): TRGBTriple; procedure ResetInfo; protected FParentThread: TThreadBounded; procedure SetParentThread( AThread: TThreadBounded ); function UpdatePar( AMandelSet: TMandelSet ): boolean; function FixParameters: boolean; public Par: TMandParameters; Colors : TColorize; constructor Create(ABitmap: TBitmap; const ProdVers: string); procedure Prepare( AMandelSet: TMandelSet; AColors: TColorize ); procedure Render( UpdatingInfo: boolean = true ); function AlgMndFlt( CR, CI :Extended ): extended; function GetPercentDrawn: Extended; procedure UpdateInfo; procedure Redraw; procedure DoProgress( Progress: Extended = -1 ); procedure DoFilter( AFilter: TFilterKind; KeepProgr: Boolean = True); procedure RestoreFilter; procedure StoreFilter; procedure MandelSetDefault( var AMandelset: TMandelSet ); property Info: TMandelInfo read FInfo; published property ProgressTimer: Cardinal read FTimer write SetTimer; property OnProgress: TProgrEvent read FOnProgress write SetOnProgress; end; TThreadBounded = class( TThread ) private FMandelbrot: TMandelbrot; FRect: TRect; FStop: boolean; FLastTime: Cardinal; FTimer: Cardinal; FCritSec: _RTL_CRITICAL_SECTION; protected procedure Stop; public constructor Create( AMandelbrot: TMandelbrot ); destructor Destroy; override; procedure Execute; override; procedure DoEvents; // property Stopped: boolean read FStop; end; implementation {uses Main; } { TThreadBounded } constructor TThreadBounded.Create( AMandelbrot: TMandelbrot ); begin inherited Create( True ); FreeOnTerminate := False; FMandelbrot := AMandelbrot; FMandelbrot.SetParentThread( self ); FStop := False; FLastTime := 0; FTimer := 500; InitializeCriticalSection( FCritSec ); end; destructor TThreadBounded.Destroy; begin DeleteCriticalSection( FCritSec ); inherited; end; procedure TThreadBounded.DoEvents; var Continue: Boolean; t: Cardinal; begin // try if assigned( FMandelbrot ) and assigned( FMandelbrot.OnProgress ) then begin // FMandelbrot.DoProgress; t := GetTickCount - FLastTime; if t > FTimer then begin EnterCriticalSection( FCritSec ); try Continue := True; FMandelbrot.OnProgress( Self, Continue, FMandelbrot.GetPercentDrawn ); FLastTime := GetTickCount; finally LeaveCriticalSection( FCritSec ); end end; end; { except on e: exception do begin OutputDebugString( PChar( e.message ) ); Stop; end; end; } end; procedure TThreadBounded.Execute; begin try FMandelbrot.Enclose( FRect, False ); finally Terminate; end; end; procedure TThreadBounded.Stop; begin FStop := true; end; { TMandelbrot } function TMandelbrot.Getvalue( x, y : integer ): Extended; begin with Par do if ( x >= 0 ) and ( x < FWidth ) and ( y >= 0 ) and ( y < FHeight ) then Result := values[ x + y * FWidth ] else Result := 0; end; procedure TMandelbrot.DrawAll( step: integer ); var nv, ky, kx: integer; CurrLine : PRGBArray; v: Extended; tCol : TRGBTriple; kys: boolean; begin nv := -1; with Par do for ky := 0 to FHeight - 1 do begin CurrLine := PRGBArray( Bmp.ScanLine[ ky ] ); kys := ( ( ky mod step ) = 0 ); for kx := 0 to FWidth - 1 do begin if step = 1 then inc( nv ) else if ( kx mod step ) = 0 then begin if kys then nv := ky * fwidth + kx else nv := ( ky div step ) * step * fwidth + kx; end; v := values[ nv ]; tCol := Colors.FromIterToColor( v ); SwitchRB( tcol ); CurrLine[ kx ] := tCol; end; end; end; procedure TMandelbrot.Orbit; var pcy, step, pcx, maxv: Extended; i, kx, ky, nv : integer; oldzpr, zpr, zpi: extended; v, tmpv: Extended; begin with Par do begin maxv := 0; step := 1 / ( FMagnitud * FHeight ); nv := 0; for ky := 0 to FHeight - 1 do begin pcy := ( FHeight shr 1 - ky ) * step + FCentImag; for kx := 0 to FWidth - 1 do begin pcx := ( kx - ( FWidth shr 1 ) ) * step + FCentReal; zpr := 0; zpi := 0; i := 0; v := 0; while i < FIter do begin inc(i); oldzpr := zpr; zpr := zpr*zpr - zpi*zpi + pcx; zpi := 2*zpi*oldzpr + pcy; tmpv := arctan2( abs( zpi - pcy ), abs( zpr - pcx ) ); // distance v := v + tmpv; if zpr*zpr + zpi*zpi > FBailout then //4 = 2^2 break; end; values[ nv ] := v; inc( nv ); if v > maxv then maxv := v; end; end; FMaxIterVal := maxv; Colors.MaxIter := round( FMaxIterVal ); end; DrawAll( 1 ); end; function TMandelbrot.BordersEqual( x, y, step: integer; Adiacents, Diagonals: boolean; var val: extended ): boolean; var i: Extended; begin i := 0; if Adiacents then begin i := getvalue( x - step, y ); Result := ( i > 0 ) and ( i = getvalue( x + step, y ) ) and ( i = getvalue( x, y - step ) ) and ( i = getvalue( x, y + step ) ); end else Result := true; if Diagonals then begin i := getvalue( x - step, y - step ); Result := Result and ( i > 0 ) and ( i = getvalue( x + step, y - step ) ) and ( i = getvalue( x - step, y + step ) ) and ( i = getvalue( x + step, y + step ) ); end; if Result then val := i; end; procedure TMandelbrot.Pass( IsOdd: boolean; Step: integer; Interpolate: boolean ); var my, kx, ky, x, y, nv: integer; CurrLine : PRGBArray; v, pcx, pcy: Extended; tCol : TRGBTriple; begin with Par do begin my := ( FHeight - 1 ) div Step; if IsOdd and Interpolate then my := my shr 1; for ky := 0 to my do begin y := ky * Step; if IsOdd and Interpolate then y := y shl 1 + Step; if y >= FHeight then break; pcy := ( FHeight shr 1 - y ) * FincI + FCentImag; CurrLine := PRGBArray( Bmp.ScanLine[ y ] ); if IsOdd and Interpolate then x := Step else if not IsOdd xor odd( ky ) then x := Step else x := 0; for kx := 0 to ( FWidth - 1 ) div ( Step shl 1 ) do begin if x >= FWidth then break; nv := x + y * FWidth; if values[ nv ] = 0 then begin // da calcolare if Interpolate and BordersEqual( x, y, Step, not IsOdd, IsOdd, v ) then begin if IsOdd then tCol := PRGBArray( Bmp.ScanLine[ y - Step ] ) [ x - Step ] else tCol := CurrLine[ x - Step ]; end else begin pcx := ( x - ( FWidth shr 1 ) ) * FincR + FCentReal; v := AlgMndFlt( pcx, pcy ); // Mandel(pcx, pcy, max); tCol := Colors.FromIterToColor( v ); SwitchRB( tcol ); end; values[ nv ] := v; CurrLine[ x ] := tCol; end; inc( x, Step shl 1 ); end; end; DoProgress; end; end; procedure TMandelbrot.Draft( Step: integer ); begin Pass( true, Step, false ); Pass( false, Step, true ); repeat Step := Step shr 1; Pass( true, Step, true ); DoProgress; Pass( false, Step, true ); DoProgress; until ( Step <= 8 ) or Application.Terminated; DrawAll( 8 ); end; procedure TMandelbrot.Interpolate( Step: integer ); begin Pass( true, Step, false ); Pass( false, Step, true ); repeat Step := Step shr 1; Pass( true, Step, true ); Pass( false, Step, true ); until ( Step = 1 ) or Application.Terminated; end; procedure TMandelbrot.Fill( ARect: TRect; AValue: Extended ); begin FillVal( ARect, AValue, false ); end; procedure TMandelbrot.FillVal( ARect: TRect; AValue: Extended; ValOnly: boolean ); var CurrLineDiff, kx, ky, nv: integer; CurrLine : PRGBArray; pcx, pcy, v: Extended; tcol: TRGBTriple; totalarea, longline: boolean; begin with ARect do begin totalarea := ( Left = 0 ) and ( Top = 0 ) and ( Right = Bmp.Width - 1 ) and ( Bottom = Bmp.Height - 1 ); longline := ( Right - Left > 256 ) or ( Bottom - Top > 256 ); end; with Par do begin v := AValue; CurrLine := PRGBArray( Bmp.ScanLine[ ARect.Top ] ); if ARect.Top <> ARect.Bottom then begin CurrLineDiff := integer( Bmp.ScanLine[ ARect.Top + 1 ] ) - integer( CurrLine ); CurrLine := PRGBArray( integer( CurrLine ) - CurrLineDiff ); end else CurrLineDiff := 0; if not ValOnly then begin tcol := Colors.FromIterToColor( Avalue ); SwitchRB( tcol ); end; for ky := ARect.Top to ARect.Bottom do begin pcy := ( FHeight shr 1 - ky ) * FincI + FCentImag; if not ValOnly then CurrLine := PRGBArray( integer( CurrLine ) + CurrLineDiff ); for kx := ARect.Left to ARect.Right do begin nv := kx + ky * FWidth; if AValue = 0 then begin pcx := ( kx - ( FWidth shr 1 ) ) * FincR + FCentReal; v := AlgMndFlt( pcx, pcy ); if not ValOnly then begin tcol := Colors.FromIterToColor( v ); SwitchRB( tcol ); end; end; values[ nv ] := v; if not ValOnly then CurrLine[ kx ] := tCol; end; if totalarea then DoProgress( ky / ARect.Bottom ); end; if longline then DoProgress; end; end; procedure TMandelbrot.CalculateBorders( ARect: TRect ); var bar: TRect; begin bar := rect( ARect.Left, ARect.Top, ARect.Right, ARect.Top ); // Top Fill( bar, 0 ); bar := rect( ARect.Left, ARect.Bottom, ARect.Right, ARect.Bottom ); //Bottom Fill( bar, 0 ); bar := rect( ARect.Left, ARect.Top + 1, ARect.Left, ARect.Bottom - 1 ); // left Fill( bar, 0 ); bar := rect( ARect.Right, ARect.Top + 1, ARect.Right, ARect.Bottom - 1 ); // right Fill( bar, 0 ); end; function TMandelbrot.BorderEqual( ARect: TRect ): extended; var k, nv: integer; v: Extended; begin with Par do begin Result := 0; // worst condition // first check the 4 corners nv := ARect.Left + ARect.Top * FWidth; v := values[ nv ]; nv := ARect.Right + ARect.Top * FWidth; if v <> values[ nv ] then exit; nv := ARect.Right + ARect.Bottom * FWidth; if v <> values[ nv ] then exit; nv := ARect.Left + ARect.Bottom * FWidth; if v <> values[ nv ] then exit; for k := ARect.Left + 1 to ARect.Right - 1 do begin nv := k + ARect.Top * FWidth; if v <> values[ nv ] then exit; nv := k + ARect.Bottom * FWidth; if v <> values[ nv ] then exit; end; for k := ARect.Top + 1 to ARect.Bottom - 1 do begin nv := ARect.Left + k * FWidth; if v <> values[ nv ] then exit; nv := ARect.Right + k * FWidth; if v <> values[ nv ] then exit; end; end; Result := v; end; procedure TMandelbrot.TraceBar( Horizontal: boolean; ARect: Trect; var r1, r2: TRect ); var Bar: TRect; begin if Horizontal then begin Bar.Left := ARect.Left + 1 ; Bar.Right := ARect.Right - 1; Bar.Top := ( ARect.Bottom + ARect.Top ) shr 1; Bar.Bottom := Bar.Top; r1 := rect( ARect.Left, ARect.Top, ARect.Right, Bar.Bottom ); r2 := rect( ARect.Left, Bar.Top, ARect.Right, ARect.Bottom ); end else begin Bar.Left := ( ARect.Right + ARect.Left ) shr 1; Bar.Right := Bar.Left; Bar.Top := ARect.Top + 1; Bar.Bottom := ARect.Bottom - 1; r1 := rect( ARect.Left, ARect.Top, Bar.Right, ARect.Bottom ); r2 := rect( Bar.Left, ARect.Top, ARect.Right, ARect.Bottom ); end; FillVal( Bar, 0, False ); end; procedure TMandelbrot.Enclose( Rect: TRect; BordersDone: boolean ); var hr, wr : integer; r1, r2: TRect; bu: Extended; begin wr := Rect.Right - rect.Left; hr := Rect.Bottom - rect.Top; if ( wr <= 12 ) and ( hr <= 12 ) then begin // too small CutBorders( Rect ); Fill( Rect, 0 ); exit; end; if not BordersDone then CalculateBorders( Rect ); bu := BorderEqual( Rect ); if ( bu > 0 ) and ( wr < Par.FWidth ) then // skip the first time begin // Fill solid CutBorders( Rect ); Fill( Rect, bu ); exit; end; if ( wr >= 32 ) and ( hr >= 32 ) then DoProgress; TraceBar( ( wr < hr ), Rect, r1, r2 ); Enclose( r1, true ); Enclose( r2, true ); end; procedure TMandelbrot.CutBorders( var Rect: TRect ); begin with Rect do begin inc( Left ); inc( Top ); dec( right ); dec( bottom ); end; end; procedure TMandelbrot.Prepare( AMandelSet: TMandelSet; AColors: TColorize ); var i: integer; begin if AMandelSet.FVersion = '' then FixParameters else UpdatePar( AMandelSet ); if assigned( Bmp ) then begin SetLength( values, par.FWidth * par.FHeight ); for i := 0 to high(values) do values[i] := 0; // set all to zeros Bmp.Width := par.FWidth; Bmp.Height := par.FHeight; Bmp.PixelFormat := pf24bit; end; if assigned( AColors ) then begin Colors := AColors; Colors.MaxIter := round( par.fiter ); end; end; procedure TMandelbrot.Render(UpdatingInfo: boolean = true); var tb1, tb2, tb3, tb4 : TThreadBounded; hh, hw: integer; begin FFilter := fkNone; if UpdatingInfo then begin ResetInfo; DoProgress( 0 ); end; try case par.FAlgo of maInterp256: begin Interpolate( 256 ); end; maInterp8: begin Interpolate( 8 ); end; maPlain: begin Fill( rect( 0, 0, par.FWidth - 1, par.FHeight - 1 ), 0 ); end; maInterpEven: begin Pass( true, 1, false ); DoProgress; Pass( false, 1, true ); end; maOrbits: begin Orbit; end; maDraft: begin Draft( 256 ); end; maBoundedMP: begin tb1 := TThreadBounded.Create( self ); tb2 := TThreadBounded.Create( self ); tb3 := TThreadBounded.Create( self ); tb4 := TThreadBounded.Create( self ); try hw := par.FWidth div 2; hh := par.FHeight div 2; tb1.FRect := rect( 0, 0, hw - 1, hh - 1 ); tb2.FRect := rect( hw, 0, par.FWidth - 1, hh - 1 ); tb3.FRect := rect( 0, hh, hw - 1, par.FHeight - 1 ); tb4.FRect := rect( hw, hh, par.FWidth - 1, par.FHeight - 1 ); tb1.Resume; tb2.Resume; tb3.Resume; tb4.Resume; while not ( tb4.Terminated and tb3.Terminated and tb2.Terminated and tb1.Terminated ) do begin Application.ProcessMessages; end; finally tb1.Free; tb2.Free; tb3.Free; tb4.Free; end; end else // maBounded: begin Enclose( rect( 0, 0, par.FWidth - 1, par.FHeight - 1 ), false ); end; end; finally FFilter := fkNone; if UpdatingInfo then begin DoProgress( 1 ); UpdateInfo; end; end; end; constructor TMandelbrot.Create(ABitmap: TBitmap; const ProdVers: string); begin FProdVers := ProdVers; Bmp := ABitmap; SetLength( values, 0 ); // mette anche a zero MandelSetDefault( Mandelset ); FTimer := 100; FLastTime := 0; FParentThread := nil; end; function TMandelbrot.AlgMndFlt(CR,CI :extended): Extended; var mi, Realqv,Sumqv,Imagqv,Realnv,Dprodv,Imagnv,PR,PI: extended; MaxItr, Iterv : integer; zeta, c, t1, t2: Tcomplex; begin with Par do begin mi := FBailout; // MaxVal; MaxItr := round( FIter ); Iterv := MaxItr; if FCQuad then begin PR:=2*CR*CI; CR:=CR*CR-CI*CI; CI:=PR; end; PR := par.FRealPert; PI := par.FImagPert; if FJulia then begin PR := CR; PI := CI; CR := par.FRealPert; CI := par.FImagPert; end; case FFormula of ffQuad: asm mov ECX, Iterv mov DX, 4100h {Flags} fld mi {MaxVal R7} fld CR {CR R6} fld CI {CI R5} fld PI {ZqI R4} fld st(0) {DPZ:=ZqI R3} fmul st(1),st {ZqI:=ZqI*DPZ R3} fadd st,st {DPZ:=DPZ+DPZ R3} fld PR {ZqR R2} fmul st(1),st {DPZ:=DPZ*ZqR R2} fmul st,st {ZqR:=ZqR*ZqR R2} fadd st,st(4) {ZqR:=ZqR+CR R2} fsub st,st(2) {ZqR:=ZqR-ZqI R2} @@start: fld st(0) {temp:=ZqR R1} fmul st(1),st {ZqR:=ZqR*temp R1} fadd st, st(0) {temp:=temp+temp R1} fxch st(2) {temp:=DPZ DPZ:=temp R1} fadd st, st(4) {temp:=temp+CI R1} fmul st(2),st {DPZ:=DPZ*temp R1} fmul st, st {temp:=temp*temp R1} fst st(3) {ZqI:=temp R1} fadd st, st(1) {temp:=ZqR+ZqI R1} fcomp st(6) {temp:=temp-MaxVal R2} fstsw AX {salva 80x87 cond.code R2} fadd st,st(4) {ZqR:=ZqR+CR R2} test AX,DX {test flag carry e zero R2} fsub st,st(2) {ZqR:=ZqR-ZqI R2} loopnz @@start mov EAX,iterv sub EAX,ECX mov Iterv,EAX fadd st,st(2) fsub st,st(4) fstp Realqv {R3} fstp DProdv {R4} fstp Imagqv {R5} finit @@Fine: end; { This is corresponding pascal code while ((Itr < MaxItr) and (ZqR+ZqI < MaxVal)) do begin inc(Itr); ZR:=ZqR-ZqI+CR; ZI:=DPZ+DPZ+CI; ZqI:=ZI*ZI; DPZ:=ZR*ZI; ZqR:=ZR*ZR; end; } ffEight: asm mov ECX, Iterv mov DX, 4100h {Flags} fld mi {MaxVal R7} fld CR {CR R6} fld CI {CI R5} fld PI {ZI R4} fld PR {ZR R3} fld st(1) {ZqI:=ZI R2} fmul st,st {ZqI:=ZqI*ZqI R2} fld st(1) {ZqR:=ZR R1} fmul st,st {ZqR:=ZqR*ZqR R1} @@start: fld st(0) {temp:=ZqR R0} fsub st,st(2) {temp:=temp-ZqI R0} fxch st(3) {temp:=ZR ZR:=temp R0} fmul st,st(4) {temp:=temp*ZI R0} fadd st, st {temp:=temp+temp R0} fst st(4) {ZI:=temp R0} fmul st, st {temp:=temp*temp R0} fstp st(2) {ZqI:=temp R1} fld st(2) {temp:=ZR R0} fmul st, st {temp:=temp*temp R0} fst st(1) {ZqR:=temp R0} fsub st,st(2) {temp:=temp-ZqI R0} fxch st(3) {temp:=ZR ZR:=temp R0} fmul st,st(4) {temp:=temp*ZI R0} fadd st, st {temp:=temp+temp R0} fst st(4) {ZI:=temp R0} fmul st, st {temp:=temp*temp R0} fstp st(2) {ZqI:=temp R1} fld st(2) {temp:=ZR R0} fmul st, st {temp:=temp*temp R0} fst st(1) {ZqR:=temp R0} fsub st,st(2) {temp:=temp-ZqI R0} fadd st, st(6) {temp:=temp+CR R0} fxch st(3) {temp:=ZR ZR:=temp R0} fmul st,st(4) {temp:=temp*ZI R0} fadd st, st {temp:=temp+temp R0} fadd st, st(5) {temp:=temp+CI R0} fst st(4) {ZI:=temp R0} fmul st, st {temp:=temp*temp R0} fstp st(2) {ZqI:=temp R1} fld st(2) {temp:=ZR R0} fmul st, st {temp:=temp*temp R0} fst st(1) {ZqR:=temp R0} fadd st, st(2) {temp:=temp+ZqI R0} fcomp st(7) {temp:=temp-MaxVal R1} fstsw AX {salva 80x87 cond.code R1} test AX,DX {test flag carry e zero R1} loopnz @@start2 jp @@cont @@start2: jp @@start @@cont: mov EAX,iterv sub EAX,ECX mov Iterv,EAX fstp Realqv {R3} fstp DProdv {R4} fstp Imagqv {R5} finit @@Fine: end; ffForth: asm mov ECX, Iterv mov DX, 4100h {Flags} fld mi {MaxVal R7} fld CR {CR R6} fld CI {CI R5} fld PR {PZ:=ZR R4} fld PI {ZqI:=ZI R3} fld st(1) {ZqR:=PZ R2} fmul st,st {ZqR:=ZqR*ZqR R2} fxch st(1) {ZqR:=ZqI ZqI:=ZqR R2} fmul st(2),st {PZ:=ZqR*PZ R2} fmul st,st {ZqR:=ZqR*ZqR R2} fxch st(1) {ZqR:=ZqI ZqI:=ZqR R2} @@start: fld st(0) {temp:=ZqR R1} fsub st,st(2) {temp:=ZqR-ZqI R1} fld st(3) {tem2:=PZ R0} fadd st,st {tem2:=tem2+tem2 R0} fadd st,st {tem2:=tem2+tem2 R0} fmul st(4),st {PZ:=PZ*tem2 R0} fmul st,st(1) {tem2:=tem2*temp R0} fadd st,st(5) {tem2:=tem2+CI R0} fstp st(2) {ZqR:=tem2 R1} fmul st,st {temp:=temp*temp R1} fsub st,st(3) {temp:=temp-PZ R1} fadd st,st(5) {temp:=temp+CR R1} fst st(3) {PZ:=temp R1} fmul st,st(1) {temp:=temp*ZqR R1} fxch st(3) {temp:=PZ PZ:=temp R1} fmul st,st {temp:=temp*temp R1} fxch st(1) {emp*temp R1}t R1}t: R1} fxch st(1) {emp*temp R1}t R1}t: R1} fxch st(1) {emp*temp stp Imagqv {emp*temp stp Imagqv {emp*temp stp Imagqv {emp*temp stp Imagqv {emp*temp stp Imagqv {emp*temp stp Imagqv {emp*temp stp Imagqv {emp*temp stp Imagqv {emp*temp stp Imagqv {emp*temp stp Imagqv {emp*temp stp Imagqv ) agqv {emp*temp stt(4) k-------gqv {e4mr+ agqvf {emp*temp stp Iation GetPe6emp stp Imal x, tp ImagT1} mnmeRprw mD R1} test AXstp magl x, tp ImagT1} {CR R6} fld CI {t, st(6) {temp: {R3} fstp DProdv t {temp:=temp*temp end; } ffEight:t {PZ:=ZR R4} fld P} fstp DProdv =ZqI ZqI:=ZqR 0tem2 R0}1) {ZqR:=ZqI ZqI:=ZqR 2 R0 R0} fadd st {Phs fstp DProdv - R1} fadd s=ZqI ZqI:=ZqR 2 R0 R fadd s=ZqI ZqI:=ZqRPZ:=PZ*tem3 R0}R fadd s=ZqI ZqI:=ZqR 6tem2 R0} fadd st,s {temp:=ZZqI R R0} fmul st(4),st { fstp Imagqv R6} fld CI {CZqR 0tem2 R0}1) {ZqR:=ZqI ZqI:=ZqR 2 R0 R fadd s=ZqI ZqI:=ZqRtem2:=PZ 2 R0- R0} fadd st {t, st {temp:=temp*temp R0} fstp {tem2:=tem2+tem2 R0} fld st(0) {test {tempp:=temp*temp R0} fst s {temp:=temp*temp {ZqR R0} fst s {temp:=Z I R0} fmul st(4),st { 6) {temp:=temp+CR R0} fxch {temp:=temp*temp R*CR R0) {test 2 R1} test AXR:=temp R0} fmul {temp:=temp+CR R1} fst st(3)0 {PZ:=temp {temp:=temp+CI R0} fst stst(4) {ZI:=temp R0} fmul stst, st {temp:=temp*temp R0} f {temp:={temp:=temp*temp R1} fxch st(1) {emp*temp R1}t R1}t R1} { fadd st, {emp*t fxch st(1) : R1} R1}t R) {emp*temp stp Imagqv {eZ tb4.FRectest AX,DX Info.Xbegin;X,DX Info.Ybegin R2Vers := Pep; is fkN:= ep; ir = Pep; ii = ep; idating = ep; i,st(4) ors v kx, ky, ended; s fkN:<tp I)hr 1; for ky := 0 to my do v tb2.Info = PZPoweDifInfo;Info tb2.Info.0; Info.0ro R2}2.Info.y; Info.yb st,st(2) ii = Info.y*Info.yt,st(2) ir = PInfo.0*Info. maxv := s fkN:= ii +ir tb2.Resume; {eing[16];tb4.FRectest AX,DX Info.Xbegin;X,DX Info.Ybegin R2c.Xbegio R2}c.YbegiC R2Vers := Pep; is fkN:= 1p; ir = Pep; ii = ep; idating = ep; i,st(4) ors v kx, ky, ended; s fkN:<tp I)hr 1; for ky := 0 to my do v tb2.Info = PZA wZSqDifInfoesumInfo; al; z = Info.y*Info.yt,st(2) ir = PInfo.0*Info. maxv := s fkN:= ii +ir tb2.Resume; {eFAspectb4.FRectest AX,DX Info.Xbegi0.5+n;X,DX Info.Ybegi0+n R2c.Xbegio R2}c.YbegiC R2Vers := Pep; is fkN:= ep; ir = Pep; ii = ep; i,st(4) ors v kx, ky, ended; s fkN:<tp I)hr 1; for ky := 0 to my do v tb2.Info = PZMul(PZMul(cumInfosumZSub(); ZSqDifInfoesogress; z = Info.y*Info.yt,st(2) ir = PInfo.0*Info. maxv := s fkN:= ii +ir tb2.Resume; {eJulia : botb4.FRectest AX,DX Info.Xbegin;X,DX Info.Ybegin R2c.Xbegio R2}c.YbegiC R2t1 = PZPoweDicum0.15 0.15conda R) e 1;lia t bo R2Vers := Pep; is fkN:= ep; ir = Pep; ii = ep; i,st(4) ors v kx, ky, ended; s fkN:<tp I)hr 1; for ky := 0 to my do v tb2.Info = PZA wZMul(PZSqDiInfosumtResum al; z = Info.y*Info.yt,st(2) ir = PInfo.0*Info. maxv := s fkN:= ii +ir tb2.Resume; {e strtb4.FRectest AX,DX Info.Xbegin;X,DX Info.Ybegin R2c.Xbegio R2}c.YbegiC R2Vers := Pep; is fkN:= ep; ir = Pep; ii = ep; i,st(4) ors v kx, ky, ended; s fkN:<tp I)hr 1; for ky := 0 to my do v tb2.Info = PZPoweDicumInfos; z = Info.y*Info.yt,st(2) ir = PInfo.0*Info. maxv := s fkN:= ii +ir tb2.Resume; {eSter := rounest AX,DX Info.XbegiCR+n;X,DX Info.YbegiCI+n R2c.Xbegio R2}c.YbegiC R2Vers := Pep; is fkN:= ep; ir = Pep; ii = ep; i,st(4) ors v kx, ky, ended; s fkN:<tp I)hr 1; for ky := 0 to my do v tb2.Info = PZMul(PZSteiInfosumcs; z = Info.y*Info.yt,st(2) ir = PInfo.0*Info. maxv := s fkN:= ii +ir tb2.Resume; {eSteTaer := rounest AX,DX Info.XbegiCR+n;X,DX Info.YbegiCI+n R2c.Xbegio R2}c.YbegiC R2Vers := Pep; is fkN:= ep; ir = Pep; ii = ep; i,st(4) ors v kx, ky, ended; s fkN:<tp I)hr 1; for ky := 0:= False Z<-C*(steiZ+taeiZ))) 0 to my do v tb2.Info = PZMul(PC,PZSteiPZA wZnfo;ZTae wZnfoesogreal; z = Info.y*Info.yt,st(2) ir = PInfo.0*Info. maxv := s fkN:= ii +ir tb2.Resume; {eSpidertb4.FRectest AX,DX Info.Xbegin;X,DX Info.Ybegin R2c.Xbegio R2}c.YbegiC R2Vers := Pep; iz = ep; ir = Pep; is fkN:= iep; i,st(4) ors v kx, ky, ended; s fkN:<tp I)hr 1; for ky := 0 to my do v tb2.Info = PZA wc ZSqDifInfoesog tb2.c = PZA Info;ZDiv wc 2 )l; z = Info.y*Info.yt,st(2) ir = PInfo.0*Info. maxv := s fkN:= ii +ir tb2.Resume; {e etismtb4.FRectest AX,DX Info.Xbegin;X,DX Info.Ybegin R2c.Xbegio R2}c.YbegiC R2Vers := Pep; iz = ep; ir = Pep; is fkN:= iep; i,st(4) ors v kx, ky, ended; s fkN:<tp I)hr 1; for ky := 0 to my do v tb2.t1 = PZSqDifZA wZA wc ZSqDifInfoesog, -1sog tb2.t2 = PZSqDifZA wZA wc Info;Info , -2) tb2.Info = PZDiv w enal; z = Info.y*Info.yt,st(2) ir = PInfo.0*Info. maxv := s fkN:= ii +ir tb2.Resume; {xten s fkN:= ir +ii if U:= ir -ii +io ifo th:= idating +iC d := nil; i v kx, ky, function TMandelbrot.A extendeeighyCar.FWidth; R2Vers:FWidth; R2 hh := par.FHft + 1 to v.FRect := rect( 0, 0, hw - 1, hVepstas:FWidth; R2 hh := par.FHft + 1 to i v +not ExtraParmp.SLe wLe ws fkN: 0.5n ExtraPar2itmap ExtraParmpto Le wLe wagqv, for kx ExtraPar2 dth + Le w2eate( self ); t( 0, 0, hw - 1, hSum: FWidth; R2 hh := par.FHft + 1to sqrt ws fkN: ExtraParm;magqExtraParm ProdVer + bfor kx}e( self ); t( 0, 0, hw - 1, h :FWidth; R2 hh := par.FHft + 1= ii ExtraParm;mgqExtraParm ProdVer + bfor kx ^ 2}e( self ); t( 0, 0, hw - 1, h if: FWidth; R2 hh := par.FHft + 1to r ExtraParm;magqExtraParm ProdVer + bfor kx ^ 2}e( self ); t( 0, 0, hw - 1, h : FWidth; R2 hh := par.FHft + 1to sqrt ws fkN: ExtraParm v.r.FHgqExtraParm P1 + bfor kx}e( self ); t( 0, 0, hw - 1, hSumI: FWidth; R2 hh := par.FHft + 1to v notsqrt ws fkN: ExtraParm );.FHgqExtraParm P1 + bfor kx}e( self ); t( 0, 0, hw - 1, hBioM:FWidth; R2 hh := par.FH; r <tp )begin(i <tp )b if IsOdd and ft + 1 to ve( self ); t( ) then x :ft + 1 to 1te( self ); t( 0, 0, hw - 1, hRadiant:FWidth; R2 hh := par.FHft + 1 to ( nv := 0ifo th, r Real ap ExtraParmp +n0.5n *ProdVerstmap ExtraParmp= pi *P2e( self ); t( 0, 0, hw - 1, h Rad:FWidth; R2 hh := par.FHft + 1 to v +not nv := 0ifo th, r Real ap ExtraParmp +n0.5n stmap ExtraParmp= pi *P2hh := par.FHe( self ); t( 0, tb2.R) then ft + 1 to rodVers; B t( 0, 0, hw - rea := ( Left = 0 ) aTMandelbrot.A extendeeighyCar.FWidth; R2VntMod:FWidth; R2 hh := par.FHrt + 1 to sqrt ws fkN: ExtraParm;mgqExtraParm ProdVer + bfor kx}e( self ); t( 0, 0, hw - 1, h ntRadiant:FWidth; R2 hh := par.FHft + 1 to ( nv := 0ifo th, r Real ap ExtraParmp +n0.5n *ProdVerstmap ExtraParmp= pi *P2e( self ); t( 0, tb2.R) then ft + 1 to rodVers; B t( 0, 0, hw - reaom ); end; ft + 1 < end elsft + 1 to 1e-1ep; ; magqv R) TRectemlors.re some errdelSin rothqv r1 par.FHeight - 1 ), f2 ) then kip the first time ):= Step shr 1; Pass( tru else 1; nterpEvenagqv, tc enrToFloa ( tcdatingInfo: agqv, enrToFloa ( datingInfo: agqv, enrToFloa d ( ,and tb2.Teragqv,R tb4.enrToFloa ( R ,antingInfo: agqv,t do enrTo nt ( t dodatingInfo: agqv,t do <in if Isagqv,t do 32gInfo: agqv, ); ienrTo nt ( ); datingInfo: agqv, ); <in if Isagqv, ); i32gInfo: agqv,AspectRtb4.enrToFloa ( AspectR,and tb2.Teragqv, end;ABit end;tb2.Teragqv, for kx ienrTo nt ( for kx, 4d tb2.Teragqv, mi, tb4.enrToFloa ( mi, datingInfo: agqv,Realnv,Dtb4.enrToFloa ( Realnv,DdatingInInfo: Fa= pa= 'gin Co256' function TMandelbrot.Aidth := paFIter Bmp.He 0, hw - rea := ( Left Fa= pa= 'gin Co8' function TMandelbrot.Aidth := paFIter Bmp8 0, hw - rea := ( Left Fa= pa= 'gin Co2' function TMandelbrot.Aidth := paFIter Bmp 0, hw - rea := ( Left Fa= pa= 'axIte' function TMandelbrot.Aidth := paFIteraxIte 0, hw - rea := ( Left Fa= pa= ' Re' function TMandelbrot.Aidth := paFIter Re 0, hw - rea := ( Left Fa= pa= 'erp25' function TMandelbrot.Aidth := paFItererp25 0, hw - rea := ( Left Fa= pa= ' sMP' function TMandelbrot.Aidth := paFIterpolate( 2 0, hw - rea := ( Left FHei endunction TMandelbrot.Aidth := paFIterpolate(ume; FeighyC='R.^2+I.^2 (mod)' if Isagqv,eighyCab4.eum := ( Left FeighyC='Pot ial' if Isagqv,eighyCab4.Vepstas := ( Left FeighyC='R ar.FHes*mod' end; endlegacy if Isagqv,eighyCab4. := ( Left FeighyC='R a.FHes*mod' end if Isagqv,eighyCab4. := ( Left FeighyC='R ar.FHes+mod' end; endlegacy if Isagqv,eighyCab4.SumI := ( Left FeighyC='R a.FHes+mod' end if Isagqv,eighyCab4.SumI := ( Left FeighyC=' ^2' end if Isagqv,eighyCab4. := ( Left FeighyC='Realinary^2' end if Isagqv,eighyCab4.Real := ( Left FeighyC='R Bmntc mod' end if Isagqv,eighyCab4.VntMod := ( Left FeighyC='R Bmntc radiant' end if Isagqv,eighyCab4.VntRadiant := ( Left FeighyC='Biomorph' end if Isagqv,eighyCab4.BioM := ( Left FeighyC=' adiant' end if Isagqv,eighyCab4.Radiant := ( Left FeighyC='Radiant+R ' end if Isagqv,eighyCab4.V Rad := ( Left = 0 ) aagqv,eighyCab4.V gInInfo: Fd; ='Z<-Z^4+C' function TMandelbrot.Aidth = ABi:=e; ;elbrot.Aidth d; :=e R0 0, hw - rea := ( Left Fd; ='Z<-Z^3+C' function TMandelbrot.Aidth = ABi:=e; ;elbrot.Aidth d; :=e mp*t 0, hw - rea := ( Left Fd; ='Z<-Z^2+C^2' function TMandelbrot.Aidth = ABi:=Val := maot.Aidth d; :=e ABi 0, hw - rea := ( Left Fd; ='Z<-Z^3+C^2' function TMandelbrot.Aidth = ABi:=Val := maot.Aidth d; :=e mp*t 0, hw - rea := ( Left Fd; ='Z<-Z^8+C' function TMandelbrot.Aidth = ABi:=e; ;elbrot.Aidth d; :=e E ); de- rea := ( Left Fd; ='Z<-Z^Z+C' function TMandelbrot.Aidth = ABi:=e; ;elbrot.Aidth d; :=e Zei 0, hw - rea := ( Left Fd; ='Z<-Z^2+Z+C' function TMandelbrot.Aidth = ABi:=e; ;elbrot.Aidth d; :=e ing[16]; 0, hw - rea := ( Left Fd; ='Z<-Z^C' function TMandelbrot.Aidth = ABi:=e; ;elbrot.Aidth d; :=e ZeiC 0, hw - rea := ( Left Fd; ='Z<-Z*C*(1-Z)' function TMandelbrot.Aidth = ABi:=e; ;elbrot.Aidth d; :=e FAspec 0, hw - rea := ( Left Fd; ='Z<-steiZ)+C' function TMandelbrot.Aidth = ABi:=e; ;elbrot.Aidth d; :=e ite 0, hw - rea := ( Left Fd; ='Z<-C*(siZ+tiZ)))' end; Z<-C*(steiZ+taeiZ))) 0 to myTMandelbrot.Aidth = ABi:=e; ;elbrot.Aidth d; :=e iteTae 0, hw - rea := ( Left Fd; ='Spider' function TMandelbrot.Aidth = ABi:=e; ;elbrot.Aidth d; :=e ipider 0, hw - rea := ( Left Fd; =' etism' function TMandelbrot.Aidth = ABi:=e; ;elbrot.Aidth d; :=e etism 0, hw - rea := ( Left Fd; ='Julia : bo' function TMandelbrot.Aidth = ABi:=e; ;elbrot.Aidth d; :=e Julia : bo 0, hw - rea := ( Left = 0 ) aTMandelbrot.Aidth d; :=e ABi 0, hw - idth = ABi:=e; ;elbrot.Areaom ); DoProgreb2.F time elsft + 1 to ( wr >= 32 )om ); xcept := ( 2 ) then else // mlsft + 1 to e; ;elbrot be par.FHeight - 1 ), f ( wr >= 32 ):= Step shr 1; Pass( trpuctor TMandnterpEv xtendeeighyCar.FWidthSum: = 0 ) aTMandelbrot.A ExtraParmpto ,R t/itmap: TBielbrot.Areaom ); Vepstas:FWidth;TMandelbrot.A ExtraParmpto Le wLe w, for kx ;elbrot.A ExtraPar2 = Ph + Le w2eate( self ); FTim : FWidth;TMandelbrot.A ExtraParmpto 1t/itmap: TBielbrot.Areaom ); SumI:FWidth;TMandelbrot.A ExtraParmpto 1t/itmap: TBielbrot.Areaom ); if: = 0 ) aTMandelbrot.A ExtraParmpto ,R t/i w, for kx *w, for kx ielbrot.Areaom ); :FWidth;TMandelbrot.A ExtraParmpto ,R t/i w, for kx *w, for kx ielbrot.Areaom ); ntMod:FWidth;TMandelbrot.A ExtraParmpto ,R t/itmap: TBielbrot.Areaom ); ntRadiant:FWidth;TMandelbrot.A ExtraParmpto pi *P2ielbrot.Areaom ); BioM:FWidth;TMandelbrot.A ExtraParmpto ,R t/itmap: TBielbrot.Areaom ); Radiant:FWidth;TMandelbrot.A ExtraParmpto pi *P2ielbrot.Areaom ); Rad: FWidth;TMandelbrot.A ExtraParmpto pi *P2ielbrot.Areaom ); Left = 0 ) a ExtraParmpto 0;elbrot FWidth;FHe) c rect( Bdrpuc>= 32 ) and ColorVal to ,R tbaxree; . Ususume eect. be,R tbkx c nTM diffee( rSin some f; ) and IARecto 1t/i( *w, r2, true ); IARRpto ,RARec* AspectRgInInfo: FMind; , tc - IARRp*not ValOnlDoProrue ); MindI , - ,RARec*= PRGBArraDoProrue ); ft + 1 to Val := maot xcept := ( ft + 1 to e; ;elbrot be AMandelSet.FVersion =d; end Filu elserst time ); exit; en DoProgreor T exit; exit; ,ree; eFile:='sume' N>= :=' nd000' tc:='-0.75' :='0' :='0.4' := paFIt' s' Vers:='100' Offlser='0' ValOnr='550' RGBArrr='530' AspectR:='1' Priority:='HBAr' end;:=e; ;el gin //='' map: TB:='128' mi, r='0' Realnv,Dr='0' eighyC:='Pot ial' d; :='Z<-Z^2+C(N; l)' omm //='Sp*te Rf ar.al' n :=D( Bn ToStr(N;w) ronor='0:00:00:000' serve '' tn usatr T FSp*t mssume; FW AMandelSet.FVersion = 'draw exit; Do ( tbegin // too small CutBorders( ogrOnrminated ion.TerTrmina t finally Onrminatedab4.Velbrot.Fi// too small CutBorders( ogrBound ion.TerCardResu finally Bounded:Velbrot.Fi// too small CutBorders( Terminated arminated end; = -nd tb2.Tnally Co inu := Step shr 1; Pas end; plose( rect( 0, TMandelbrot.Prepare( Alose( rect( 0 Te ts;FHuses s own criti ser.FHes 0:= Falselose( rect( 0 Synchronize(Alose( rect( 0 Te ts;)elbrot t.Fi/eft end; plOnrminateda TMandelbrot.Prepare( A; rminateda= Fillgin( rminateda= 1illgin( GgrBockC tb1. begin > Bounde) function TMandelbrot.ACo inu to Val := maot Onrminated( Self,ACo inu , rminatedaielbrot.Aht, AReCo inu if IsOdSysUtils.Abo,Dprodv,Ima begin GgrBockC t 0, hw - reaom ); end;// too snally andesHee(: dResu o 0;el small CutBorders( Te ( A erT Ki Keeprmina: Beters TUpdatingInnally th, ky, kx); Update be in Updateh, vup, vdw, vlf,Avrg end; fi if Trip]; 0, hw x87 n : dResuhr 1; PasateBandesHee( tworks oeger2^n ndes ;-)elbrx87 n to VndesHee(hr 1; tb4.A end; Keeprmina wr := Rect.Right - r] := 0;FH) ialize; enructor TMandidth;y proce tb1.Re} test AX,DX frx87 n <>BandesHee( ] then exit s.re'nda new tc; bet87 cs>= ng); int = 0 ) a be=in ( ( w.Sc nineDiffy ]aielbrot.Ath:= i nv* fwe ); - exit; ndidth;x proce ht - 1 ); 1; for ky := 0 to my do Ath:ate( self );( bar, 0 ); bar := re fr t4.Resumeb if IsOdd hh := par.tcoc Colors:FromVersToColor eate( self ); S chRB(.tcoc ate( self ); 0, tb2.R) then hh := par. fr nv> end els self );(up bar, 0 ); b- fwe ); ]e( self ); ) then x(up bar,; hh := par. fr nv<e tb1.Red els self );(dw bar, 0 ); b+ fwe );]e( self ); ) then x(dw bar,; hh := par. fr xv> end els self );(lf bar, 0 ); b- 1]e( self ); ) then x(lf bar,; hh := par. fr xv<e ht - 1 ); d els self );(rg bar, 0 ); b+ 1]e( self ); ) then x(rg bar,; hh := par.tcoc edVelbrsToCol( ,eh, vup, vdw, vlf,Avrg ate( self ); 0,te( self ); [r xvr Rec s; B t( 0, 0, hw - Keeprmina wr := Recttttt.Right - r] nv/= PRGBArra1.Res ielbrot.Areaom ); be par.FHeight - 1 ), f ( edVelbrsToCol( erT Ki VtcdaVtcUpdaVtcDowndaVtcht - 1Vtcar.Le end; )if Trip]; 0, hnally sat, lh, hu := end; fi lum: Bytehr 1; Pasxtende tMaxItr, IkEdg;tb4.FRectest AX,DX l( barab Fl not, 0 ect , 0down t , 0l , 0 bu v/4 ielbrot.Al( barmp.Sl( /0, FalIter 0, hw - l( barrmp.Sl( *Sl( *Sl(t gammat4.30, hw - lur: TR255p.SVal Al( *S255pielbrot.Art + 1.rgbtBlu to lurielbrot.Art + 1.rgbtGreen to lurielbrot.Art + 1.rgbtRe lurielbrot.A tb3.kBumpertb4.FRectest AX,DX lh:= i ot, 0 ec- , 0down ) +not, 0l - , 0 bu v v/2ielbrot.Al( barmp.Sl( /0, FalIter 0, hw - l( barrmp.Sl( *Sl( *Sl(t gammat4.30, hw - lur: TRVal Al( *S127b+ 128pielbrot.Art + 1.rgbtBlu to lurielbrot.Art + 1.rgbtGreen to lurielbrot.Art + 1.rgbtRe lurielbrot.A tb3.kColorBumpertb4.FRectest AX,DX sa1 to 1te( self lh:= i ot, 0 ec- , 0down ) +not, 0l - , 0 bu v v/2ielbrot.Ahu to Fl /0, FalIterpielbrot.AHSLto (hu , sat, lh, rt + 1)ielbrot.A tb3.kRGBArrrb4.FRectest AX,DX lh:= i, 0down -t, 0 e;0, hw - lur: TRVal A(Sl( /0, FalItern *P127b+ 128pielbrot.Art + 1.rgbtRe lurielbrot.Alh:= i, 0ar.Left vtcht -;0, hw - lur: TRVal A(Sl( /0, FalItern *P127b+ 128pielbrot.Art + 1.rgbtGreen to lurielbrot.Alur: TRVal A(S Fl /0, FalIterp *S255pielbrot.Art + 1.rgbtBlu to lurielbrot.A tb3.kUnsharpMasktb4.FRectest AX,DX lh:= i VtcDownb+ VtcUpb+ VtcrocedureVtcht -u v/4ielbrot.Alh:= i +i Vtcp.Sl( ielbrot.Aht,l <t; d els sell( barmelbrot.A eft l( >0, FalIterpd els sell( bar, FalIter 0, hw - rt + 1 to Colors:FromVersToColor l( ielbrot.A tb3.kAverag;tb4.FRectest AX,DX l( bar VtcDownb+ VtcUpb+ VtcrocedureVtcht -u v/4ielbrot.Alh:= i(i +ilvv v/2ielbrot.Aht,l <t; d els sell( barmelbrot.A eft l( >0, FalIterpd els sell( bar, FalIter 0, hw - rt + 1 to Colors:FromVersToColor l( ielbrot.A tb3.kNois;tb4.FRectest AX,DX rt + 1 to Colors:FromVersToColor Fl ielbrot.Aht,Rt -om w2ea = end els sel hh := pa toHSL( rt + 1, hu , sat, lh ate( self );l( barf ar(l b+ Rt -om 0.5n- 0.25ate( self );HSLto (hu , sat, lh, rt + 1)ielbrot.A2.Resume; tb3.k s:FWidth;TMandelbrot.A; <>BVtcUpbllgin( <>BVtcDown ) gin( <>BVtcht -u vgin( <>BVtcR bu vd els selRt + 1 to Colors:FromVersToColor Fl elbrot.A eft els sel hh := pat + 1.rgbtBlu to 0; hh := pat + 1.rgbtGreen to 0; hh := pat + 1.rgbtRe 0ielbrot.A2.Resume; tb3.kCristals:FWidth;TMand FWidth;; <>BVtcUpbllded; <>BVtcDown ) ded; <>BVtcht -u vded; <>BVtcR bu vd els selRt + 1 to Colors:FromVersToColor Fl elbrot.A eft els sel hh := pat + 1.rgbtBlu to 0; hh := pat + 1.rgbtGreen to 0; hh := pat + 1.rgbtRe 0ielbrot.A2.Resume; tb3.kEq gin //FWidth;TMand FWidth;; and .Fbaxr= and .FMnd d els sell( barvalelbrot.A eft els sell( bar(i Vtcp.Sand .Fbinv v/( and .Fbaxr- and .FMnd , Fali gInInfo: elRt + 1 to Colors:FromVersToColor l( ielbrot.A tb3 tS chRB(.Rt + 1 )om ); be par.FHeight - 1 ), fGetPercentDrawn end; finally h, vbax); Updated, nd); Update exit; enF not or TMandelbrot.Creavbax bar, Falht - 1*= PreadBounded.Create( selN:= iep; 0ielbrotn 0ielbrot,st(4) <tvbax } test AX,DX fr, 0 ); vvr = end els selo Atd elbrot.A eft els selo Ad ielbrot.Ah Av,ant tget umebpo everyant elbrot.A tb3 trt + 1 to dv/( td +Ad ielbr frrt + 1 >=t; d elsrt + 1 to 0.9999999999ot.Fi// too small CutBorders( nated and tb1.Tnally h, vbax); Updatep: ^ begin est AX,DX setand tb1.T enF not or TMandelbrot.Creavbax bar, Falht - 1*PreadBounded.Cr Updatep bar@, 0 ); 0bar := reidthv procevbax } test AX,DX frp^ =0, FalIterpd els selI F nsideC tielbrot.Aht,( Min = -nd vgin( p^ < Fbinv vd els selFbinvto p^ielbrot.Aht,(( x = -nd vgin( p^ > Fbaxr) vded; p^ < , FalIterp d els selFbax barp^ielbrot.Ah Ap ielbrot.A tb3 t// too small CutBorders( setand tb1.T exit; enF not or TMandelbrot.CreaF nsideC t 0ielbrot Min := -nielbrot Max bar-nielbrot tFMndc t 0ielbr// too small CutBorders( otore end;nally ev tb4.F end;// too small CutBorders( store end;nally FHe)fors.re wanda R) treaighy fr ev t<>BResumeb if Do ( ev tbegin // too small CutBorders( ogrose( rect( 0(Aect( 0: Tect( 0polate( finally se( rect( 0, 0,Aect( 0egin // too s// 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/