sub min {(sort {$a<=>$b} @_ )[0];}
sub max {(sort {$a<=>$b} @_ )[-1];}
####
sub min_max {
my( $min, $max ) = ( 1e-308, 1e308 );
for(@_){
$min = $_ if $_ < $min;
$max = $_ if $_ > $max;
}
return ($min, $max);
}
####
#! perl -slw
use strict;
use GD;
use GD::Polyline;
use Data::Dumper;
use constant PI => 3.14159265359;
sub Turtle {
my( $dir, $polyline, $xy ) = ( 0, new GD::Polyline, [ 0, 0 ] );
return sub {
return $polyline unless @_;
$dir += shift||0;
my $dist = shift||0;
$xy->[0] += $dist*sin(PI*$dir/180);
$xy->[1] += $dist*cos(PI*$dir/180);
$polyline->addPt( @$xy );
return;
};
}
sub plotxy {
my( $polyline, $file, $scale ) = @_;
$polyline->scale( $scale, $scale, 0, 0 ) if $scale;
my( $centre_x, $centre_y ) = $polyline->centroid;
$polyline->offset( int($centre_x+10), 10 + -int(2*$centre_y) );
my( $width, $height ) = ($polyline->bounds)[2,3];
my $image = new GD::Image( $width + 10, $height + 10 );
my $white = $image->colorAllocate(255,255,255);
my $black = $image->colorAllocate(0,0,0);
$image->transparent($white);
$image->interlaced('true');
$image->polyline( $polyline, $black );
open(IMG, ">$file");
binmode IMG;
print IMG $image->jpeg;
}
sub koch {
my ($turtle, $d, $level) = @_ ;
if ($level==0) {$turtle->(0,$d); return 1;}
$turtle->( 0,0); koch($turtle,$d/3,$level-1);
$turtle->(-60,0); koch($turtle,$d/3,$level-1);
$turtle->(120,0); koch($turtle,$d/3,$level-1);
$turtle->(-60,0); koch($turtle,$d/3,$level-1);
}
my $turtle = Turtle();
map {$turtle->(120, 0); koch($turtle, 170, 4);} 0..2;
plotxy($turtle->(), 'koch.jpg', 3);
# Minkowski Island
sub minkowski {
my ($turtle, $d, $level) = @_ ;
if ($level==0) {$turtle->(0,$d); return 1;}
minkowski($turtle,$d/4,$level-1);
$turtle->(-90,0); minkowski($turtle,$d/4,$level-1);
$turtle->( 90,0); minkowski($turtle,$d/4,$level-1);
$turtle->( 90,0); minkowski($turtle,$d/4,$level-1);
minkowski($turtle,$d/4,$level-1);
$turtle->(-90,0); minkowski($turtle,$d/4,$level-1);
$turtle->(-90,0); minkowski($turtle,$d/4,$level-1);
$turtle->( 90,0); minkowski($turtle,$d/4,$level-1);
}
$turtle = Turtle();
map {$turtle->(90,0); minkowski($turtle, 150, 3);} 0..3;
plotxy($turtle->(), 'minkowski.jpg', 2);
# Dragon Curve
sub dragon1 {
my ($turtle, $d, $level) = @_ ;
if ($level==0) {$turtle->(0,$d); return 1;}
dragon($turtle,$d*0.707,$level-1);
$turtle->(-90,0); dragon1($turtle,$d*0.707,$level-1);
}
sub dragon {
my ($turtle, $d, $level) = @_ ;
if ($level==0) {$turtle->(0,$d); return 1;}
dragon($turtle,$d*0.707,$level-1);
$turtle->(90,0); dragon1($turtle,$d*0.707,$level-1);
}
$turtle = Turtle();
dragon($turtle, 150, 12);
plotxy($turtle->(), 'dragon.jpg', 2);
####
$xy->[0] += $dist*sin(PI*$dir/180);
$xy->[1] += $dist*cos(PI*$dir/180);
####
my %sin_d; sub sin_d{ my $d=shift; $sin_d{$d} || ( $sin_d{$d} = sin(PI*$d/180) ); }
my %cos_d; sub cos_d{ my $d=shift; $cos_d{$d} || ( $cos_d{$d} = cos(PI*$d/180) ); }
....
$xy->[0] += $dist * sin_d($dir);
$xy->[1] += $dist * cos_d($dir);
...