Готовая программа

#!/usr/bin/perl

use warnings;

use utf8;
use open qw/:locale/;
use Image::Magick;
use Getopt::Long qw/:config no_ignore_case bundling/;

my $radius=100;
my $outputFile='Mandelbrot.png';
my $region='-2.4:-1.2:.8:1.2';
my $density=400;

sub help()
{
	STDERR->print(<<__HELP__);
mandelbrot.pl ⟨опции⟩

⟨опции⟩:
	-o, --output-file ⟨имя графического файла⟩
		имя выходного файла («$outputFile»)
	-r, --region ⟨umin⟩:⟨vmin⟩:⟨umax⟩:⟨vmax⟩
		прямоугольник на комплексной плоскости ($region)
	-d, --density ⟨целое число⟩
		количество пикселов на единичном отрезке ($density)
	-R, --radius ⟨вещественное число⟩
		радиус ($radius)
	-h, --help
		показать эту подсказку
__HELP__
	exit;
}

GetOptions
	(
		'o|output-file=s'	=>\$outputFile,
		'r|region=s'		=>\$region,
		'd|density=f'		=>\$density,
		'R|radius=f'		=>\$radius,
		'h|help'			=>\&help,
	);

my ($left, $bottom, $right, $top)=split ':', $region;
my $squaredRadius=$radius**2;

sub iterate($$)
{
	my ($u, $v)=@_;
	my ($tx, $ty)=my ($hx, $hy)=(0, 0);
	my $n=0;
	while()
	{
		($tx, $ty)=($tx**2-$ty**2+$u, 2*$tx*$ty+$v);
		($hx, $hy)=($hx**2-$hy**2+$u, 2*$hx*$hy+$v) for 0, 1;
		return 1/sqrt($n/4+1) if $tx**2+$ty**2>=$squaredRadius;
		return -1/sqrt($n/4+1) if (($tx-$hx)**2+($ty-$hy)**2)*$squaredRadius<1;
		$n++;
	}
}

my ($w, $h)=map { int($density*$_) } ($right-$left, $top-$bottom);

my $image=Image::Magick->new(size=>"${w}x$h");
$image->ReadImage('NULL:black');
$image->Color(color=>'black');
$image->Comment("region=$region density=$density radius=$radius");
$image->Set(depth=>8);

for my $i(0..$w-1)
{
	printf "\e[K\rГотово: \%d\%\%", $i/$w*100;
	STDOUT->flush;
	for my $j(0..$h-1)
	{
		my $jConjugate=2*$density*$top-$j;
		my $color;
		if($jConjugate<$j and $jConjugate>=0)
		{
			$color=[$image->GetPixel(x=>$i, y=>$jConjugate)];
		}
		else
		{
			my $value=iterate($i/$density+$left, -$j/$density+$top);
			$color=$value<0? [-$value, 0, 0]: [0, $value, 0];
		}
		$image->SetPixel(x=>$i, y=>$j, color=>$color);
	}
}

if((my $message=$image->Write($outputFile)) eq '')
{
	my $size=-s $outputFile;
	print "\e[K\rФайл «$outputFile» (${w}×$h, $size байт) записан.\n";
}
else
{
	die "\n$message\n";
}
Информатика-54© А. Н. Швец