Perlでドラゴン曲線を描く
続いてはドラゴン曲線。
use v5.14; use strict; use warnings; use Imager; use constant N => 16; use constant WIDTH => 900; use constant HEIGHT => 900; my $margin = 240; my ( $x0, $y0 ) = ( $margin, HEIGHT - $margin ); my @gen1 = ( # [ 0.0, 0.0 ] は不要 [ 0.5, 0.5 ], [ 1.0, 0.0 ] ); my @gen2 = ( # [ 0.0, 0.0 ] は不要 [ 0.5, -0.5 ], [ 1.0, 0.0 ] ); my $points = [ [ 0, 120 ], [ 512, 120 ] ]; my $img = Imager->new( xsize => WIDTH, ysize => HEIGHT ); $img->box( filled => 1, color => 'white' ); foreach my $n ( 0..N ) { $img->box( filled => 1, color => 'white' ); if ( 0 < $n ) { $points = generate( $points ); } my @tmp = map { [ int($x0 + $_->[0]), int($y0 - $_->[1]) ]; } @{$points}; $img->polyline( points => \@tmp, color => 'black' ); my $dst_file = ($0 =~ s/\.pl//r) . "_${n}.png"; $img->write( file => $dst_file ) or die $img->errstr; } sub generate { my ( $points ) = @_; my $cnt = scalar( @{$points} ); my @result = ( $points->[0] ); for (my $i=1; $i<$cnt; $i++) { my ( $st, $en ) = ( $points->[$i-1], $points->[$i] ); my $dx = $en->[0] - $st->[0]; my $dy = $en->[1] - $st->[1]; push @result, map { my ( $x, $y ) = ( $_->[0], $_->[1] ); # x2 = $x * cos(a) - $y * sin(a) + st.x; # y2 = $x * sin(a) - $y * cos(a) + st.y; # sin(a) = dy / 1.0, cos(a) = dx / 1.0 [ ($x * $dx) - ($y * $dy) + $st->[0], ($x * $dy) + ($y * $dx) + $st->[1] ]; } ( ($i & 0x1) ? @gen1 : @gen2 ); } return \@result; }
これは、書き直した際にバグが入って、
バグが入る事によって面白い絵ができることがあるんだけど、
今回はそんなことはなくて、ちょっと悲しかったです。
おしまい。
Leave a Comment