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