Data-Turtle
view release on metacpan or search on metacpan
eg/lindenmayer-gd view on Meta::CPAN
4 => { # Dragon curve: distance=10, theta=90
axiom => 'FX',
X => 'X+YF+',
Y => '-FX-Y',
},
5 => { # SierpiÅski arrowhead curve: distance=1, theta=60
axiom => 'F',
F => 'G-F-G',
G => 'F+G+F',
},
6 => { # SierpiÅski triangle: distance=4, theta=120
axiom => 'F-G-G',
F => 'F-G+F+G-F',
G => 'GG',
},
7 => { # Koch snowflake: distance=3, theta=60
axiom => 'F++F++F',
F => 'F-F++F-F',
X => 'FF',
},
8 => { # SierpiÅski carpet: distance=4, theta=90
axiom => 'F',
F => 'F+F-F-F-G+F+F+F-F',
G => 'GGG',
},
9 => { # Koch island: distance=5, theta=90
axiom => 'F-F-F-F',
F => 'F-F+F+FF-F-F+F',
},
10 => { # Koch islands and lakes: distance=5, theta=90
axiom => 'F+F+F+F',
F => 'F+f-FF+F+FF+Ff+FF-f+FF-F-FF-Ff-FFF',
f => 'ffffff',
},
11 => { # Grid: distance=5, theta=90
axiom => 'F-F-F-F',
F => 'FF-F-F-F-FF',
},
12 => { # Terndrils: distance=5, theta=90
axiom => 'F-F-F-F',
F => 'FF-F--F-F',
},
);
my $string = $rule{ $opts{rule} }{axiom};
my $turtle = Data::Turtle->new(
width => $opts{width},
height => $opts{height},
x => $opts{width} / 2,
y => $opts{center} ? $opts{height} / 2 : $opts{height},
);
my $img = GD::Image->new( $opts{width}, $opts{height} );
my %color = (
white => $img->colorAllocate( 255, 255, 255 ),
black => $img->colorAllocate( 0, 0, 0 ),
);
$img->transparent( $color{white} );
$img->interlaced('true');
my @statestack;
my %translate = (
'f' => sub { $turtle->forward( $opts{distance} ) },
'F' => \&forward,
'G' => \&forward,
'-' => sub { $turtle->turn( - $opts{theta} ) },
'+' => sub { $turtle->turn( $opts{theta} ) },
'M' => sub { $turtle->mirror },
'[' => sub { push @statestack, [ $turtle->get_state ] },
']' => sub { $turtle->set_state( @{ pop @statestack } ) },
);
for ( 1 .. $opts{repeat} ) {
$string =~ s/(.)/defined($rule{ $opts{rule} }{$1}) ? $rule{ $opts{rule} }{$1} : $1/eg;
}
warn "$string\n";
for my $command ( split //, $string ) {
$translate{$command}->() if exists $translate{$command};
}
print $img->png;
sub forward {
my @line = $turtle->forward( $opts{distance} );
if ( $turtle->pen_down ) {
$img->setThickness( $line[5] );
$img->line( @line[ 0 .. 3 ], $color{ $line[4] } );
}
}
( run in 1.205 second using v1.01-cache-2.11-cpan-98e64b0badf )