Task: Julia set






PHP: set_time_limit(300);
header("Content-Type: image/png");

class Julia {
	
	static private $started = false;
	
	public static function start() {
		if (!self::$started) {
			self::$started = true;
			new self;
		}
	}
	
	const AXIS_REAL 	= 0;
	const AXIS_IMAGINARY 	= 1;
	const C 		= [-0.75, 0.1];
	const RADII 		= [1, 0.5];
	const CENTER 		= [0, 0];
	const MAX_ITERATIONS 	= 100;
	const TICK_SPACING 	= 0.001;
	
	private $maxDistance;
	private $imageResource;
	private $whiteColorResource;
	private $z0 = [];
	
	private function __construct() {
		$this->maxDistance = max($this->distance(self::C), 2);
		$this->imageResource = imagecreate(
			$this->coordinateToPixel(self::RADII[self::AXIS_REAL], self::AXIS_REAL),
			$this->coordinateToPixel(self::RADII[self::AXIS_IMAGINARY], self::AXIS_IMAGINARY)
		);
		imagecolorallocate($this->imageResource, 0, 0, 0);
		$this->whiteColorResource = imagecolorallocate($this->imageResource, 255, 255, 255);
		
		for ($x = self::CENTER[self::AXIS_REAL] - self::RADII[self::AXIS_REAL];
		$x <= self::CENTER[self::AXIS_REAL] + self::RADII[self::AXIS_REAL]; $x += self::TICK_SPACING) {
			$z0[self::AXIS_REAL] = $x;
			
			for ($y = self::CENTER[self::AXIS_IMAGINARY] - self::RADII[self::AXIS_IMAGINARY];
			$y <= self::CENTER[self::AXIS_IMAGINARY] + self::RADII[self::AXIS_IMAGINARY]; $y += self::TICK_SPACING) {
				$z0[self::AXIS_IMAGINARY] = $y;
				$iterations = 1;
				do {
					$z0 = $this->q($z0);
					$iterations++;
				} while($iterations < self::MAX_ITERATIONS && $this->distance($z0) <= $this->maxDistance);
				
				if ($iterations !== self::MAX_ITERATIONS) {
					imagesetpixel(
						$this->imageResource,
						$this->coordinateToPixel($x, self::AXIS_REAL),
						$this->coordinateToPixel($y, self::AXIS_IMAGINARY),
						$this->whiteColorResource
					);
				}
				$z0[self::AXIS_REAL] = $x;
			}
		}
	}
	
	public function __destruct() {
		imagepng($this->imageResource);
		imagedestroy($this->imageResource);
	}
	
	private function q($z) {
		return [ ($z[self::AXIS_REAL] ** 2) - ($z[self::AXIS_IMAGINARY] ** 2) + self::C[self::AXIS_REAL],
                       (2 * $z[self::AXIS_REAL] * $z[self::AXIS_IMAGINARY]) + self::C[self::AXIS_IMAGINARY] ];
	}
	
	private function distance($z) {
		return sqrt( ($z[self::AXIS_REAL] ** 2) + ($z[self::AXIS_IMAGINARY] ** 2) );
	}
	
	private function coordinateToPixel($coordinate, $axis) {
		return ($coordinate + self::RADII[$axis]) * (self::TICK_SPACING ** -1);
	}
}

Julia::start();




COBOL: IDENTIFICATION DIVISION.
PROGRAM-ID. JULIA-SET-PROGRAM.
DATA DIVISION.
WORKING-STORAGE SECTION.
01  WS-COMPLEX-CONSTANT.
    05 C-REAL             PIC S9V999.
    05 C-IMAGINARY        PIC S9V999.
01  WS-ARGAND-PLANE.
    05 X                  PIC S9(9)V999.
    05 Y                  PIC S9(9)V999.
01  WS-COMPLEX-VARIABLE.
    05 Z-REAL             PIC S9(9)V999.
    05 Z-IMAGINARY        PIC S9(9)V999.
01  WS-TEMPORARY-RESULTS.
    05 X-SQUARED          PIC S9(9)V999.
    05 Y-SQUARED          PIC S9(9)V999.
    05 X-TIMES-Y          PIC S9(9)V999.
    05 Z-REAL-SQUARED     PIC S9(9)V999.
01  WS-LOOP-COUNTERS.
    05 HORIZONTAL         PIC 999.
    05 VERTICAL           PIC 999.
    05 ITERATIONS         PIC 99.
77  WS-PLOT-CHARACTER     PIC X.
PROCEDURE DIVISION.
INPUT-COMPLEX-CONSTANT-PARAGRAPH.
    ACCEPT C-REAL      FROM CONSOLE.
    ACCEPT C-IMAGINARY FROM CONSOLE.
CONTROL-PARAGRAPH.
    PERFORM OUTER-LOOP-PARAGRAPH  VARYING VERTICAL   FROM 1 BY 10
    UNTIL VERTICAL IS GREATER THAN 320.
    STOP RUN.
OUTER-LOOP-PARAGRAPH.
    PERFORM COMPUTATION-PARAGRAPH VARYING HORIZONTAL FROM 1 BY 10
    UNTIL HORIZONTAL IS GREATER THAN 560.
    DISPLAY '' UPON CONSOLE.
COMPUTATION-PARAGRAPH.
    SUBTRACT 280   FROM HORIZONTAL GIVING X.
    SUBTRACT 160   FROM VERTICAL   GIVING Y.
    DIVIDE   X     BY   200        GIVING X.
    DIVIDE   Y     BY   100        GIVING Y.
    MOVE     '#'   TO   WS-PLOT-CHARACTER.
    PERFORM COMPLEX-MULTIPLICATION-PARAGRAPH
    VARYING ITERATIONS FROM   1  BY      1
    UNTIL   ITERATIONS        IS GREATER THAN 50
    OR      WS-PLOT-CHARACTER IS EQUAL   TO   SPACE.
    DISPLAY WS-PLOT-CHARACTER UPON CONSOLE WITH NO ADVANCING.
COMPLEX-MULTIPLICATION-PARAGRAPH.
    MULTIPLY X         BY   X         GIVING X-SQUARED.
    MULTIPLY Y         BY   Y         GIVING Y-SQUARED.
    SUBTRACT Y-SQUARED FROM X-SQUARED GIVING Z-REAL.
    ADD      C-REAL    TO   Z-REAL.
    MULTIPLY X         BY   Y         GIVING X-TIMES-Y.
    MULTIPLY X-TIMES-Y BY   2         GIVING Z-IMAGINARY.
    ADD C-IMAGINARY    TO   Z-IMAGINARY.
    MULTIPLY Z-REAL    BY   Z-REAL    GIVING Z-REAL-SQUARED.
    IF  Z-REAL-SQUARED IS   GREATER   THAN   10000 THEN
    MOVE SPACE         TO   WS-PLOT-CHARACTER.
    MOVE Z-REAL        TO   X.
    MOVE Z-IMAGINARY   TO   Y.