Nadesłany przez Tomasz Lubiński, 26 lipca 2011 22:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.Pobierz pełne rozwiązanie.
Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.
IFS - Delphi/Unit1.pas:
//IFS //(c) 2011 by Tomasz Lubinski //www.algorytm.org unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Math; type TForm1 = class(TForm) Fractal: TImage; Label1: TLabel; Label2: TLabel; IterNum: TEdit; Button1: TButton; Fun: TComboBox; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; // Render area coordinates minX: Real = -8.0; maxX: Real = 8.0; minY: Real = 11.0; maxY: Real = -5.0; // IFS data a, b, c, d, e, f, p: array[1..9] of Real; funCnt: Integer = 0; implementation {$R *.DFM} // add new function to IFS procedure addFunction(paramA, paramB, paramC, paramD, paramE, paramF, paramP: Real); begin funCnt := funCnt+1; if (funCnt < 9) then begin a[funCnt] := paramA; b[funCnt] := paramB; c[funCnt] := paramC; d[funCnt] := paramD; e[funCnt] := paramE; f[funCnt] := paramF; p[funCnt] := paramP; end; end; // removes all functions procedure clearFunctions(); begin funCnt := 0; end; procedure SetFunctions(); begin clearFunctions(); case Form1.Fun.ItemIndex of 0: begin addFunction(0.5, 0.0, 0.0, 0.5, -0.5, 0.5, 0.3333); addFunction(0.5, 0.0, 0.0, 0.5, -0.5, -0.5, 0.3333); addFunction(0.5, 0.0, 0.0, 0.5, 0.5, -0.5, 0.3333); minX := -1.0; maxX := 1.0; minY := -1.0; maxY := 1.0; end; 1: begin addFunction(0.787879, -0.424242, 0.242424, 0.859848, 1.758647, 1.408065, 0.895652); addFunction(-0.121212, 0.257576, 0.151515, 0.053030, -6.721654, 1.377236, 0.052174); addFunction(0.181818, -0.136364, 0.090909, 0.181818, 6.086107, 1.568035, 0.052174); minX := -8.0; maxX := 8.0; minY := 11.0; maxY := -1.0; end; 2: begin addFunction(0.824074, 0.281428, -0.212346, 0.864198, -1.882290, -0.110607, 0.787473); addFunction(0.088272, 0.520988, -0.463889, -0.377778, 0.785360, 8.095795, 0.212527); minX := -8.0; maxX := 8.0; minY := 11.0; maxY := -1.0; end; 4: begin addFunction(0.1400, 0.0100, 0.0000, 0.5100, -0.0800, -1.3100, 0.20); addFunction(0.4300, 0.5200, -0.4500, 0.5000, 1.4900, -0.7500, 0.20); addFunction(0.4500, -0.4900, 0.4700, 0.4700, -1.6200, -0.7400, 0.20); addFunction(0.4900, 0.0000, 0.0000, 0.5100, 0.0200, 1.6200, 0.40); minX := -5.0; maxX := 5.0; minY := 5.0; maxY := -5.0; end; 5: begin addFunction( 0.0500, 0.0000, 0.0000, 0.4000, -0.0600, -0.4700, 0.142); addFunction(-0.0500, 0.0000, 0.0000, -0.4000, -0.0600, -0.4700, 0.142); addFunction( 0.0300, -0.1400, 0.0000, 0.2600, -0.1600, -0.0100, 0.142); addFunction(-0.0300, 0.1400, 0.0000, -0.2600, -0.1600, -0.0100, 0.142); addFunction( 0.5600, 0.4400, -0.3700, 0.5100, 0.3000, 0.1500, 0.142); addFunction( 0.1900, 0.0700, -0.1000, 0.1500, -0.2000, 0.2800, 0.142); addFunction(-0.3300, -0.3400, -0.3300, 0.3400, -0.5400, 0.3900, 0.142); minX := -1.0; maxX := 1.0; minY := 1.0; maxY := -1.0; end; else begin addFunction(0.0, 0.0, 0.0, 0.16, 0.0, 0.0, 0.01); addFunction(0.85, 0.04, -0.04, 0.85, 0.0, 1.6, 0.85); addFunction(0.2, -0.26, 0.23, 0.22, 0.0, 1.6, 0.07); addFunction(-0.15, 0.28, 0.26, 0.24, 0.0, 0.44, 0.07); minX := -5.0; maxX := 5.0; minY := 10.5; maxY := 0.0; end; end; end; procedure TForm1.Button1Click(Sender: TObject); var x, xtmp, y, ytmp, r: Real; ratioX, ratioY, prob: Real; i, j, n, curr, biggest, level: Integer; data: array of Integer; begin // initialize all variables SetFunctions(); ratioX := (maxX - minX) / Fractal.Width; ratioY := (maxY - minY) / Fractal.Height; SetLength(data, Fractal.Width*Fractal.Height); for i:=0 to (Fractal.Width*Fractal.Height)-1 do data[i] := 0; x := 0; y := 0; // Clear image Fractal.Canvas.Brush.Color := clWhite; Fractal.Canvas.Rectangle(0, 0, Fractal.Width, Fractal.Height); Fractal.Canvas.Brush.Color := clBlack; n := StrToInt(IterNum.Text); randomize(); for i:=1 to n do begin // Choose random function r := Random; curr := 0; prob := 0; for j:=1 to funCnt do begin prob := prob + p[j]; if (prob > r) then begin curr := j; break; end; end; // Perform calculation xtmp := a[curr]*x + b[curr]*y + e[curr]; ytmp := c[curr]*x + d[curr]*y + f[curr]; x := xtmp; y := ytmp; // Mark point Inc(data[Floor((x - minX)/ratioX) * Fractal.Width + Floor((y - minY)/ratioY)]); end; // Check range biggest := data[0]; for i:=1 to (Fractal.Width*Fractal.Height)-1 do if (data[i] > biggest) then biggest := data[i]; // Generate image for i:=0 to Fractal.Height-1 do for j:=0 to Fractal.Width-1 do if (data[j+i*Fractal.Width] > 0) then begin level := Floor((ln(data[j+i*Fractal.Width])/ln(biggest)) * 255); Fractal.Canvas.Pixels[i,j] := rgb(128-(level div 2), 255-level, 128 - (level div 2)); end; Fractal.Refresh(); end; end.