|
#!/usr/bin/perl
|
|
use GD;
|
|
use Turtle;
|
|
|
|
sub flower
|
|
{
|
|
my $flower=shift;
|
|
my ($width, $height)=$flower->getBounds();
|
|
my ($x,$y)=$turtle->state();
|
|
$im->copy($flower, $x-$width/2, $y-$height/2, 0, 0, $width, $height\
|
|
);
|
|
}
|
|
|
|
####################################
|
|
# This hash translates from turtle
|
|
# symbols into actual Perl code.
|
|
####################################
|
|
# S => Step Forward
|
|
# - => Turn Counter-clockwise
|
|
# + => Turn Clockwise
|
|
# f,g,h => Flower
|
|
# M => Mirror
|
|
# [ => Begin Branch
|
|
# ] => End Branch
|
|
# { => Begin polygon
|
|
# } => End polygon
|
|
%translate=(
|
|
'S' => sub{$turtle->forward($changes->{"distance"}, $changes-\
|
|
>{"motionsub"});},
|
|
'-' => sub{$turtle->turn(-$changes->{"dtheta"});},
|
|
'+' => sub{$turtle->turn($changes->{"dtheta"});},
|
|
'M' => sub{$turtle->mirror();},
|
|
'[' => sub{push(@statestack, [$turtle->state()]);},
|
|
']' => sub{$turtle->setstate(@{pop(@statestack)});},
|
|
'{' => sub{$poly=new GD::Polygon; $changes=\%polychanges;},
|
|
'}' => sub{$im->filledPolygon($poly, $light_green); undef $poly;\
|
|
$changes=\%stemchanges;},
|
|
'f' => sub{flower($flower);},
|
|
'g' => sub{flower($flower2);},
|
|
'h' => sub{flower($flower3);},
|
|
);
|
|
######################################
|
|
# And this one controls the actual
|
|
# development of the L-system itself
|
|
######################################
|
|
|
|
%rule=(
|
|
'A'=>'GS[---fA][++MB]',
|
|
'B'=>'C',
|
|
'C'=>'A',
|
|
'f'=>'g',
|
|
'g'=>'h',
|
|
'h'=>'',
|
|
'G'=>'HS',
|
|
'H'=>'IS',
|
|
'I'=>'GLMS',
|
|
'L'=>'[{S+S+S+S+S+S}]',
|
|
);
|
|
# Set some parameters
|
|
%stemchanges=(distance => 2.8, dtheta => .06, motionsub => su\
|
|
b{$im->line(@_, $dark_green);});
|
|
%polychanges=(distance => 3, dtheta => .4, motionsub => sub{\
|
|
$poly->addPt(@_[0..1]);});
|
|
$changes=\%stemchanges;
|
|
$repetitions=10;
|
|
$imagesize=400;
|
|
# Create the main image
|
|
$im=new GD::Image($imagesize, $imagesize);
|
|
# Allocate some colors for it
|
|
$white=$im->colorAllocate(255,255,255);
|
|
$dark_green=$im->colorAllocate(0,128,0);
|
|
$light_green=$im->colorAllocate(0,192,0);
|
|
# Create the flower images
|
|
open(IN, "flower.gif") or die $!;
|
|
$flower=newFromGif GD::Image(IN);
|
|
close(IN);
|
|
open(IN, "flower2.gif") or die $!;
|
|
$flower2=newFromGif GD::Image(IN);
|
|
close(IN);
|
|
open(IN, "flower3.gif") or die $!;
|
|
$flower3=newFromGif GD::Image(IN);
|
|
close(IN);
|
|
# Create the turtle, at the midpoint of the bottom
|
|
# edge of the image, pointing up.
|
|
|
|
$turtle=new Turtle($imagesize/2, $imagesize, 0, 1);
|
|
|
|
# Finally, actually apply the rules to the axiom
|
|
|
|
$string="A"; # Axiom
|
|
for (1..$repetitions)
|
|
{
|
|
$string =~ s/./defined ($rule{$&}) ? $rule{$&} : $&/eg;
|
|
print "Finished pass $_...\n";
|
|
}
|
|
foreach $cmd (split(//, $string))
|
|
{
|
|
if ($translate{$cmd}) {&{$translate{$cmd}}();}
|
|
}
|
|
print "Executed...\n";
|
|
#$im->transparent($white);
|
|
open(OUT, ">tree.gif") or die $!;
|
|
print OUT $im->gif;
|
|
close(OUT);
|
|
print "Done.\n";
|