2014年6月17日火曜日

Barnsley fern in Perl and GD フラクタル図形 バーンスレイのシダ



これは、Barnsley fernというフラクタルの画像です。名前は、イギリスの数学家であるMichael Barnsleyから来たそうです。

PerlとGD(GD::Simple)を使えば簡単に作成できます。

use GD::Simple;
use strict;
sub transform {
 my @ret = ();
 my ($x, $y, $w, $h) = @_;
 $ret[0] = int (($x+2.2)*$w/5);
 $ret[1] = int ((10-$y)*$h/10);
 return @ret;
}
#         a, b, c   d,   e, f
my @w1 = (   0,      0,     0, 0.16, 0, 0.00);
my @w2 = ( 0.85,  0.04, -0.04, 0.85, 0, 1.60);
my @w3 = ( 0.20, -0.26,  0.23, 0.22, 0, 1.60);
my @w4 = (-0.15,  0.28,  0.26, 0.24, 0, 0.44);
my $x = 0;
my $y = 0;
my @p = (0.01, 0.85, 0.07, 0.07);
my @p1 = ($p[0]*10000,($p[0]+$p[1])*10000,($p[0]+$p[1]+$p[2])*10000);
my $i = 0;
my $max = 800000;
my $x1 = 0;
my $y1 = 0;
my @wt = ();
my $j;
my @ret;
my $imgW = 960;
my $imgH = 1024;
# create a new image
my $img = GD::Simple->new($imgW,$imgH);
# draw a red rectangle with blue borders
$img->bgcolor('black');
$img->fgcolor('green');
my $black = $img->colorAllocate(0,0,0);
my $green = $img->colorAllocate(0,255,0);
$img->rectangle(0,0,$imgW,$imgH,$black);
$img->fill(50,50,$black);
$img->transparent($black);
@ret = &transform($x, $y, $imgW, $imgH);
$img->setPixel($ret[0], $ret[1], $green);
for ($i=0; $i<$max; $i++) {
  my $id=int(rand(10000));
  if ($id < $p1[0] ) {
    @wt = (@w1);
  }
  elsif ($id < $p1[1]) {
    @wt = (@w2);
  }
  elsif ($id < $p1[2]) {
    @wt = (@w3);
  }
  else {
    @wt = (@w4,0);
  }
  $x1 = $x*$wt[0] + $y*$wt[1] + $wt[4];
  $y1 = $x*$wt[2] + $y*$wt[3] + $wt[5];
  @ret = &transform($x1, $y1, $imgW, $imgH);
  $img->setPixel($ret[0], $ret[1], $green);
  $x = $x1;
  $y = $y1;
}
#output the image
open( OUT, "> fern.png") or die( "Cannot open file: graph.jpg" );
binmode OUT;
print OUT $img->png;

0 件のコメント:

コメントを投稿