; Koch Snowflake to KochIsland :size :level repeat 3 [KSide :size :level rt 120] end to KSide :size :level if :level = 0 [fd :size stop] KSide :size / 3 :level - 1 lt 60 KSide :size / 3 :level - 1 rt 120 KSide :size / 3 :level - 1 lt 60 KSide :size / 3 :level - 1 end #### #! /usr/local/bin/perl -w use strict; use GD; # ----------------------------------------------------------- use constant PI => 3.14159265359; # ----------------------------------------------------------- # turtle as in LOGO's turtle # Usage: $turtle = turtle(); # $turtle->($turn_right_x_degree, $forward_x_points); # $xy = $turtle->(); sub turtle { my ($h, $xy) = (0, [[0],[0]]); # h = heading (0 - north, 90 - east, etc) return sub { $h = $h + (shift || 0); # accumulative turns in degree my $d = shift || 0; # distance $xy->[0][scalar(@{$xy->[0]})] = $d*sin(PI*$h/180) + $xy->[0][$#{@{$xy->[0]}}]; $xy->[1][scalar(@{$xy->[1]})] = $d*cos(PI*$h/180) + $xy->[1][$#{@{$xy->[1]}}]; return $xy; }; } # ----------------------------------------------------------- # Koch Snowflake 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'); # ----------------------------------------------------------- # ----------------------------------------------------------- # 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'); # ----------------------------------------------------------- # ----------------------------------------------------------- # 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'); # ----------------------------------------------------------- # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Sub for Plotting # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # sub min {(sort {$a<=>$b} @_ )[0];} # ---------------------------------------------------------------- sub max {(sort {$a<=>$b} @_ )[-1];} # ---------------------------------------------------------------- sub plotxy { my $xy = shift; my $file = shift; my $scale = shift || 1; # ------------------------------------------------------- my @x = @{$xy->[0]}; my @y = @{$xy->[1]}; my $x_min = min(@x); my $y_min = min(@y); map {$x[$_]=$scale*($x[$_]-$x_min)} 0..$#x; map {$y[$_]=$scale*($y[$_]-$y_min)} 0..$#y; my $x_width = max(@x) - 0; my $y_width = max(@y) - 0; # ------------------------------------------------------- my $image = new GD::Image($x_width,$y_width); my $white = $image->colorAllocate(255,255,255); my $black = $image->colorAllocate(0,0,0); $image->transparent($white); $image->interlaced('true'); $image->line($x[$_-1],$y[$_-1],$x[$_],$y[$_],$black) for 1..$#x; $image = $image->copyFlipVertical() ; open(IMG, ">$file"); binmode IMG; print IMG $image->jpeg; } #### # Turtle as in LOGO's Turtle {package turtle; use constant PI => 3.14159265359; sub new {return bless({h=>0,xy=>[[0],[0]]});} sub rt {$_[0]->{h}=$_[0]->{h}+$_[1];} # right turn by x degrees sub fd { # forward by x points my ($h, $xy, $d) = ($_[0]->{h}, $_[0]->{xy}, $_[1]); $xy->[0][scalar(@{$xy->[0]})] = $d*sin(PI*$h/180) + $xy->[0][$#{@{$xy->[0]}}]; $xy->[1][scalar(@{$xy->[1]})] = $d*cos(PI*$h/180) + $xy->[1][$#{@{$xy->[1]}}]; $_[0]->{xy} = $xy; return $xy; } } # ----------------------------------------------------------- # Koch Snowflake sub koch { my ($turtle, $d, $level) = @_ ; if ($level==0) {$turtle->fd($d); return 1;} $turtle->rt( 0); koch($turtle, $d/3,$level-1); $turtle->rt(-60); koch($turtle, $d/3,$level-1); $turtle->rt(120); koch($turtle, $d/3,$level-1); $turtle->rt(-60); koch($turtle, $d/3,$level-1); } # ----------------------------------------------------------- my $turtle = turtle->new(); map {$turtle->rt(120); koch($turtle, 170, 4);} 0..2; # ----------------------------------------------------------- plotxy($turtle->{xy}, 'koch.jpg'); # ----------------------------------------------------------- # Minkowski Island sub minkowski { my ($turtle, $d, $level) = @_ ; if ($level==0) {$turtle->fd($d); return 1;} minkowski($turtle,$d/4,$level-1); $turtle->rt(-90); minkowski($turtle,$d/4,$level-1); $turtle->rt( 90); minkowski($turtle,$d/4,$level-1); $turtle->rt( 90); minkowski($turtle,$d/4,$level-1); minkowski($turtle,$d/4,$level-1); $turtle->rt(-90); minkowski($turtle,$d/4,$level-1); $turtle->rt(-90); minkowski($turtle,$d/4,$level-1); $turtle->rt( 90); minkowski($turtle,$d/4,$level-1); } # ----------------------------------------------------------- $turtle = turtle->new(); map {$turtle->rt(90); minkowski($turtle, 150, 3);} 0..3; # ----------------------------------------------------------- plotxy($turtle->{xy}, 'minkowski.jpg'); # ----------------------------------------------------------- # ----------------------------------------------------------- # Dragon Curve sub dragon1 { my ($turtle, $d, $level) = @_ ; if ($level==0) {$turtle->fd($d); return 1;} dragon($turtle,$d*0.707,$level-1); $turtle->rt(-90); dragon1($turtle,$d*0.707,$level-1); } sub dragon { my ($turtle, $d, $level) = @_ ; if ($level==0) {$turtle->fd($d); return 1;} dragon($turtle,$d*0.707,$level-1); $turtle->rt(90); dragon1($turtle,$d*0.707,$level-1); } # ----------------------------------------------------------- $turtle = turtle->new(); dragon($turtle, 150, 12); # ----------------------------------------------------------- plotxy($turtle->{xy}, 'dragon.jpg'); #### use constant PI => 3.14159265359; # ----------------------------------------------------------- # Turtle Graph my $h=0; my @x=(0); my @y=(0); sub rt {$h = $h + shift;} sub fd { $x[scalar @x] = $_[0]*sin(PI*$h/180) + $x[$#x]; $y[scalar @y] = $_[0]*cos(PI*$h/180) + $y[$#y]; } sub reset_xy {$h=0; @x=(0); @y=(0);} # ----------------------------------------------------------- # ----------------------------------------------------------- # Koch Snowflake sub koch { my ($d, $level) = @_ ; if ($level==0) {fd($d); return 1;} rt( 0); koch($d/3,$level-1); rt(-60); koch($d/3,$level-1); rt(120); koch($d/3,$level-1); rt(-60); koch($d/3,$level-1); } # ----------------------------------------------------------- map {rt(120); koch(170, 4);} 0..2; # ----------------------------------------------------------- plotxy([\@x,\@y], 'koch.jpg'); # ----------------------------------------------------------- # ----------------------------------------------------------- # Minkowski Island sub minkowski { my ($d, $level) = @_ ; if ($level==0) {fd($d); return 1;} minkowski($d/4,$level-1); rt(-90); minkowski($d/4,$level-1); rt( 90); minkowski($d/4,$level-1); rt( 90); minkowski($d/4,$level-1); minkowski($d/4,$level-1); rt(-90); minkowski($d/4,$level-1); rt(-90); minkowski($d/4,$level-1); rt( 90); minkowski($d/4,$level-1); } # ----------------------------------------------------------- reset_xy(); # if necessary map {rt(90); minkowski(150, 3);} 0..3; # ----------------------------------------------------------- plotxy([\@x,\@y], 'minkowski.jpg'); # ----------------------------------------------------------- # ----------------------------------------------------------- # Dragon Curve sub dragon1 { my ($d, $level) = @_ ; if ($level==0) {fd($d); return 1;} dragon($d*0.707,$level-1); rt(-90); dragon1($d*0.707,$level-1); } sub dragon { my ($d, $level) = @_ ; if ($level==0) {fd($d); return 1;} dragon($d*0.707,$level-1); rt(90); dragon1($d*0.707,$level-1); } # ----------------------------------------------------------- reset_xy(); # if necessary dragon(150, 12); # ----------------------------------------------------------- plotxy([\@x,\@y], 'dragon.jpg');