Mandelbrot explorer

This project estimates the Mandelbrot set using the HTML5 canvas. It’s one of my longest running projects that has been implemented in PHP, SVG, HTML5 canvas, HTML tables, and even in ROOT.

Overview

This projects presents a wide range of different challenges. The aim is to create a fractal browser that pushes the operating environment to the limit in terms of performance, while still being user friendly and responsive. In its current iteration the user clicks on the region of the fractal they wish to explore and the project zooms in to that region. The user can change the way the fractal is coloured by changing the palette its properties. They can also move from the Mandelbrot set to the corresponding Julia set. There is also the option to explore the cubic Mandelbrot set. Past iterations have included even more fractals, including Newton iterations and generalised Julia sets. However these have been removed in this iteration as they should be refactored into a separate fractal class rather than inserted by hand.

Challenges

Challenge: The algorithm must be responsive and make reasonable use of memory.
Solution: The iterations used in the algorithm can be expensive when the image approaches several hundred thousand pixels. Currently the algorithm uses a pixel object to manage the colour at a given point, and for arbitrarily large images a single pixel object is used in order to reduce the cost of creating and storing large numbers of these objects. The current iteration uses Javascript in the user’s browser, and most modern browsers deal with excessive memory usage sensibly, killing particularly bad cases. It is not desirable to cap a user’s capabulities when it comes to image size, so instead the algorithm forces the browser to fail relatively safely and without major inconvenience. Previously this project ran on PHP on a shared server, so memory use had to be monitored and was formally enforced on the server, making failure modes potentially dangerous. Once the canvas became available I switched to using it very quickly. Even so, running PHP locally overnight to generate very large images is still a sensible use of resounces. There are probably other areas where savings could be made. (Resolved, to be revisited)
Challenge: The algorithm must make reasonable use of CPU.
Solution: In many cases the fractals take several tens of thousands of iterations per pixel for several thousand pixels, leading to large CPU usage. In the context of Javascript this can cause serious performance issues for the user, affecting their whole computing experience and not just that associated with the browser session. To mitigate this the iterations are interrupted every $$100 ms$$ and forced to wait for $$10 ms$$ before continuing. In addition when several small canvases are populated they are pushed into a queue which is processed serially with interruptions. This reduces the impact on the user’s CPU significantly leading to much smoother performance and better response to user input. Even so, this should be revisited to make further savings and be more responsive to the user’s inputs. (Resolved, to be revisited)
Challenge: The user interface must be intuitive.
Solution: In some senses it will never be possible ot make the user interface entirely transparent, given the technical nature of the fractal’s inner workings. In spite of this the way the user navigates is relativelt straightforward, but more improvments can and should be made. (Resolved, to be revisited)
Challenge: The palettes should be easy to edit.
Solution: The asethetic properties of the fractals often depend on the choice of palette. The palette scales can be manipulated, using slders on the log scale. This solution borrows from another project being developed in parallel, and leads to an easier interpretation of the scaling and distorting of the palette scale. This method should be tested in a “focus group” style environment. The user should be able to create and store a palette from scratch with their own choice of colours stops. (Resolved, to be revisited)
Challenge: The user should be able to store fractals.
Solution: The user can currently choose to save a fractal to the server, storing the $$(x,y)$$ coordinates, zoom, and other factors. This uses AJAX requests with a PHP and MySQL backend, which has become fairly standard in my projects by now. This comes with the usual MySQL injection overheads and PHP safety issues. In the future, as the number of fractals in the gallery increases, the gallery should be orgainsed in some manner to reduce bandwidth and CPU usage. (Resolved, to be revisited)
Challenge: The project should support arbitrary fractals for future expansion.
Solution: At the moment the fractal algorithms are hard coded into the project. This needs to be more object oriented in the future so that other developers can contribute their own fractals. (Partially resolved, to be revisited)

Conway’s game of life

Conway’s game of life is a very famous mathematical model with a rich variety of “creatures” that can interact with one another. This script is a simple interactive sandbox where the user can “paint” cells to create different shapes. There are a number of predefined boards that the user can choose to investigate some small and interesting patterns as they evolve.

Overview

The underlying mathematics is very simple. Conway’s game of life follows three simple rules:

1. A dead cell comes to life if there are three adjacent cells which are alive.
2. A living cell dies if there are fewer than two adjacent cells which are alive.
3. A living cell dies if there are more than three adjacent cells which are alive.

This is achieved by simply iterating over the board where each cell has two possible states (dead/alive) as well as the state from the previous turn. This procedure is then wrapped up in a series of window.setTimeout calls to allow the board to evolve.

Challenges

Challenge: The user must be able to paint cells to make shapes. The interaction must match the underlying grid.
Solution: Overcoming this challenge was largely a matter of seamless performance as well as correct handling of events. This was surprisingly straightforward given the lack of cross browser support for finding the cursor position. (Resolved)
Challenge: Ideally this should be an infinite sandbox.
Solution: After toying with the idea of an unlimited size of board the stretches to match the user’s patterns it was decided that this would be unfeasible. As the size of the board increases (for example, due to gospel gliders moving off to infinity) the amount of memory required to contain the game would increase to dangerous levels. In addition the splicing of additional columns (and to a lesser extent, rows) of the board would incur a significant CPU cost. The board is sufficiently large for most interesting patterns. (Resolved)
Challenge: Saving patterns with markup.
Solution: One of the most useful features was for users to be able to share their patterns with other people. To do this there is a link which automatically updates, storing the current board as a string as a url argument. This is then parsed, which turned out to be quite simple, and centred on the board. (Resolved)

Sample output

The gospel glider gun: