Skip to content

Instantly share code, notes, and snippets.

@VienosNotes
Created November 9, 2011 19:10
Show Gist options
  • Save VienosNotes/1352560 to your computer and use it in GitHub Desktop.
Save VienosNotes/1352560 to your computer and use it in GitHub Desktop.
Mandelbrot with Perl6
use v6;
class Bitmap {
has IO $!file;
has %!header;
has $!w_count;
has $!h_count;
has $!remainder;
has $!template;
method new (Str $filename = "./output.bmp") {
self.bless(*, w_count => 0, h_count => 0, file => open($filename, :w, :bin));
}
method make_header (Int $width, Int $height) {
my $size = $width * 3 * $height;
if ($!remainder = ($width * 3) % 4) {
$size += (4 - $!remainder) * $height;
}
%!header = { filetype => "BM",
filesize => 14 + 40 + $size,
pre1 => 0,
pre2 => 0,
offset => 14 + 40,
header_size => 40,
width => $width,
height => -$height,
plane => 1,
bits_per_pixel => 24,
compress_type => 0,
image_data_size => $size,
horizontal_res => 0,
vertical_res => 0,
color_index => 0,
imp_index => 0
};
$!template = "C" x (%!header{"width"} * 3);
}
method print_header {
$!file.write(pack "A2LSSLLLLSSLLLLLL", %!header.values);
# バージョンアップで動かなくなる可能性有り
}
method push_line (@line) {
$!file.write(pack $!template, |@line);
if ($!remainder != 0) {
$!file.write(pack "C", 0) for ^(4-$!remainder);
}
}
method DESTROY {
$!file.close;
}
}
class Mandelbrot {
has Int $!width;
has Int $!height;
has Int $!center_x;
has Int $!center_y;
has Int $!scale;
has Int $!limit;
has Bitmap $!fig;
method new (Int $width!, Int $height!, Int $limit = 20) {
self.bless(*, width => $width, height => $height, limit => $limit, fig => Bitmap.new("Mandelbrot.bmp"));
}
method init {
$!fig.make_header($!width, $!height);
$!fig.print_header;
}
method calc {
my $w = 4 / $!width;
my $h = 4 / $!height;
my $i = 0;
my $cn = 0;
my @color;
for (0..20) {
@color.push([((255/20) * $_).Int, ((255/20) * $_).Int, ((255/20) * $_).Int]);
}
for (1..$!height) {
my $hyi = (2 - $h * $_) * i;
my @line;
for (1..$!width) {
my $c = ((-2) + $w * $_) + $hyi;
for (1..$!limit) {
$cn = $cn ** 2 + $c;
if ($cn.abs > 2) {
$i = $_;
last;
}
}
@line.push(@color[$i].flat);
$i = 0;
$cn = 0;
}
$!fig.push_line(@line.flat);
}
$!fig.DESTROY;
}
}
my $m = Mandelbrot.new(200,200);
$m.init;
$m.calc;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment