algorytm.org

Implementacja w Delphi/Pascal



Baza Wiedzy
wersja offline serwisu przeznaczona na urządzenia z systemem Android
Darowizny
darowiznaWspomóż rozwój serwisu
Nagłówki RSS
Artykuły
Implementacje
Komentarze
Forum
Bookmarki






Sonda
Implementacji w jakim języku programowania poszukujesz?

System Funkcji Iterowanych (IFS) - Implementacja w Delphi/Pascal
Ocena użytkownikóww: *****  / 1
SłabyŚwietny
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.
Dodaj komentarz