10
Aug '14

Bit of a fun one this time. I was having a look at some of the Stack Overflow Code Golf challenges and stumbled upon this challenge to make scripts that generate mathematical art in 140 characters or less, the idea being that you could tweet them if you so desired.

The code was mostly in C or C++ but I can read it well enough to transpose a couple of the best ones into PHP. The following to are examples of fractals; a Mandlebrot set and Julia set respectively and I think they’re amazing mathematically and beautiful aesthetically. I won’t post the generated images themselves as then you’ll miss out on the coolness of generating them yourselves. It staggers me that you can create such awesome images with so few lines of code.

Mandlebrot Set Fractal

ini_set('max_execution_time', 0);
ini_set('max_input_time', 0);

header("Content-type: image/png");

$dimension = 1200;
$y_offset = $dimension / 2;
$x_offset = 3 * ($dimension / 4);

$im = @imagecreatetruecolor($dimension, $dimension) or die('Cannot create image');

for($x = 0; $x < $dimension; $x++) {
    for($y = 0; $y < $dimension; $y++) {
        $k = find_k($x, $y);
        $red = red($k);
        $green = green($k);
        $blue = blue($k);
        $colour = imagecolorallocate($im, $red, $green, $blue);
        imagesetpixel($im, $x, $y, $colour);
    }
}

imagepng($im);
imagedestroy($im);

function red($k) {
    return $k > 31 ? 256 : $k * 8;
}

function green($k) {
    return $k > 63 ? 256 : $k * 4;
}

function blue($k) {
    return log($k) * 47;
}

function find_k($i, $j) {
    global $x_offset, $y_offset;

    $x = 0;
    $y = 0;
    $k = 0;
    $big_x = 0;
    $big_y = 0;

    while($k++ < 256 && ($big_x + $big_y <= 4)) {
        $y = 2 * $x * $y + ($j - $y_offset) / $y_offset;
        $x = $big_x - $big_y + ($i - $x_offset) / $y_offset;
        $big_x = $x * $x;
        $big_y = $y * $y;
    }

    return $k;
}

Julia Set Fractal

ini_set('max_execution_time', 0);
ini_set('max_input_time', 0);

header("Content-type: image/png");

$dimension = 1024;

$im = @imagecreatetruecolor($dimension, $dimension) or die('Cannot create image');

for($x = 0; $x < $dimension; $x++) {
    for($y = 0; $y < $dimension; $y++) {
        $k = find_k($x, $y);
        $red = red($k);
        $green = green($k);
        $blue = blue($k);
        $colour = imagecolorallocate($im, $red, $green, $blue);
        imagesetpixel($im, $x, $y, $colour);
    }
}

imagepng($im);
imagedestroy($im);

function red($k) {
    return 255 * pow(($k - 80) / 800, 3);
}

function green($k) {
    return 255 * pow(($k - 80) / 800, 0.7);
}

function blue($k) {
    return 255 * pow(($k - 80) / 800, 0.5);
}

function find_k($i, $j) {
    $x = 0;
    $y = 0;
    $k = 0;
    $big_x = 0;
    $big_y = 0;

    while($k++ < 880 && ($big_x + $big_y <= 4)) {
        $y = 2 * $x * $y + ($j * 0.000000008) - 0.645411;
        $x = $big_x - $big_y + ($i * 0.000000008) + 0.356888;
        $big_x = $x * $x;
        $big_y = $y * $y;
    }

    return $k;
}

The algorithms are not my invention and I make no claim to them. I transposed them to PHP, added the image generation code and did a few optimisations but the core mathematical formulae were produced by much smarter people than myself!