#!/usr/bin/perl # hisui1.pl - Don Yang (uguu.org) # Mandelbrot set renderer # # 10/29/05 use strict; my ($ITERATION_COUNT, $X_STEPS, $Y_STEPS, $ASPECT_RATIO); $ITERATION_COUNT = 26; $X_STEPS = 79; $Y_STEPS = 24; $ASPECT_RATIO = 1.5; # Render a point by exponentiating it repeatedly. Returns number of # iterations it takes for the number to diverge, clamped by # $ITERATION_COUNT. sub render_point($$) { my ($z_r, $z_i) = @_; my ($z0_r, $z0_i) = @_; my ($i); for($i = 0; $i < $ITERATION_COUNT && $z_r * $z_r + $z_i * $z_i <= 4.0; $i++) { ($z_r, $z_i) = ($z_r * $z_r - $z_i * $z_i + $z0_r, $z_i * $z_r * 2.0 + $z0_i); } return $i; } # Convert iteration value to character sub iter_char($) { return ($_[0] >= 26 || $_[0] < 0) ? ' ' : chr(ord('A') + $_[0]); } # Check if a particular set of coordinates is interesting by checking # for high variety of values in sampled points. sub interesting($$$$) { my ($x0, $x1, $y0, $y1) = @_; my (@v, $a, $d); @v = ( render_point($x0, $y0), render_point($x0, $y1), render_point($x1, $y0), render_point($x1, $y1), render_point(($x0 + $x1) * 0.5, ($y0 + $y1) * 0.5) ); $a = $d = 0; $a += $_ foreach @v; $a /= 5; $d += ($_ - $a) * ($_ - $a) foreach @v; return ($d / 5) > ($ITERATION_COUNT * 4.6); } # Render image sub render_image($$$$$$) { my ($x0, $x1, $xsteps, $y0, $y1, $ysteps) = @_; my ($x, $y); for($y = 0; $y < $ysteps; $y++) { for($x = 0; $x < $xsteps; $x++) { print iter_char(render_point( $x * ($x1 - $x0) / ($xsteps - 1) + $x0, $y * ($y0 - $y1) / ($ysteps - 1) + $y1)); } print "\n"; } } # Random numbers sub random_range($$) { return $_[0] + rand($_[1] - $_[0]); } # Generate coordinates randomly until an interesting one is found, # then render image. sub render_random_image() { my ($x0, $y0, $s); do { $x0 = random_range(-1, 1); $y0 = random_range(-1, 1); $s = random_range(0.1, 1); } while( !interesting($x0, $x0 + $s * $ASPECT_RATIO, $y0, $y0 + $s) ); render_image($x0, $x0 + $s * $ASPECT_RATIO, $X_STEPS, $y0, $y0 + $s, $Y_STEPS); } render_random_image();