Fractal Tree

 フラクタル図形は、図形の部分と、全体が自己相似になっているもと定義されているようです。
作図をする場合は、再帰を利用します。
詳細についてはWebで検索してください。
 フラクタル図形として一番簡単なTreeのプログラムを作ってみました。 

  Fractal Treeは、一番単純な再帰による作図です。
枝の端点から、指定した角度と長さで、二本の枝を作図し、その作図した端点から、また、二本の枝の作図を再帰で繰り返すものです。
沢山繰り返すことによって、幾何学模様を作図することが出来ます。
 自然界では植物、特にサボテンにフラクタルを見る事ができます。

 左図は、左と右の枝の角度を指定して作図をしたものです。
角度の指定を変えただけで、色々なTreeの図形を描くことができます。


プログラム

unit Main;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    LabeledEdit1: TLabeledEdit;
    LabeledEdit2: TLabeledEdit;
    Edit1: TEdit;
    UpDown1: TUpDown;
    Label1: TLabel;
    Image1: TImage;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

// trunk branch

// x, y       初期座標
// qt         幹角度
// qbl        左枝角度 qbr 右枝角度
// size       幹長さ
// scale      幹長さに対する枝の長さ比率
// n          再帰数
// m          初回幹の作図フラグ
procedure tree(x, y: integer; qt, qbl, qbr, size, scale: double; n, m : byte);
var
  x0, Y0: integer;    // 幹の座標
  xl, yl, xr, yr: integer;  // 枝の先の座標
  qtl, qtr: double;   // 枝の角度
  nsize : double;


  function radrange(qq : double): double;
  begin
    result := qq;
    if qq < 0 then result := qq + 2 * pi;
    if qq >= 2 * pi then result := qq - 2 * pi;
  end;

begin
  x0 := x;
  y0 := y;
  Form1.Image1.Canvas.Pen.Color := $0000FF + m * 17 * 256;
  // 初回のみ幹の作図をします
  Form1.Image1.Canvas.MoveTo(x, y);
  if m = 0 then begin
    Form1.Image1.Canvas.Pen.Width := 2;
    x0 := x + round(cos(qt) * size);
    y0 := y - round(sin(qt) * size);              // y座標は逆になります
    Form1.Image1.Canvas.LineTo(x0, y0);
    Form1.Image1.Canvas.Pen.Width := 1;
  end;
  // 枝の作図
  nsize := size * scale;
  xl := x0 + round(cos(qt + qbl) * nsize);
  yl := y0 - round(sin(qt + qbl) * nsize);
  Form1.Image1.Canvas.LineTo(xl, yl);
  Form1.Image1.Canvas.MoveTo(x0, y0);
  xr := x0 + round(cos(qt + qbr) * nsize);
  yr := y0 - round(sin(qt + qbr) * nsize);
  Form1.Image1.Canvas.LineTo(xr, yr);
  qtl := qt + qbl;
  qtr := qt + qbr;
  qtl := radrange(qtl);
  qtr := radrange(qtr);
  if n > 1 then begin
    dec(n);
    inc(m);                     // 幹作図無しフラグセット
    tree(xl, yl, qtl, qbl, qbr, nsize, scale, n, m);
    tree(xr, yr, qtr, qbl, qbr, nsize, scale, n, m);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  qbl, qbr, size, scale: double;
  n, ch : integer;
begin
  val(labelededit1.Text, qbl, ch);
  if ch <> 0 then begin
    application.MessageBox('左の枝の角度に間違いがあります。','注意', 1);
    exit;
  end;
  val(labelededit2.Text, qbr, ch);
  if ch <> 0 then begin
    application.MessageBox('右のの枝の角度に間違いがあります。','注意', 1);
    exit;
  end;
  val(edit1.Text, n, ch);
  if ch <> 0 then begin
    application.MessageBox('再帰数に間違いがあります。','注意', 1);
    exit;
  end;
  qbl := qbl / 180 * pi;                  // 左枝角度
  qbr := -qbr / 180 * pi;                 // 右枝角度
  with Image1.Canvas do
  begin
    Brush.Color := clBlack;
    FillRect(ClipRect);
  end;
  size := 100;
  scale := 0.7;
  tree(280, 350, pi / 2, qbl, qbr, size, scale, n, 0);
end;

end.


download Fractal_V2.zip.zip

  画像処理プログラム 作図 に戻る