The mandelbrot set is a classic fractal. It is intricate and complex, yet can be generated from a simple iterative formula. It is easy to code in environments that provide convenient access to pixels, such as DOS and fragment shaders.
To create the mandelbrot set, take a 2d grid representing the complex plane. For each point on the grid, multiply it by itself (using the rules of complex arithetic), then add the initial point. Repeat this process an arbitrary number of times. If it diverges from the origin, color it based upon how long that takes. If it stays near the origin, which means it is in the mandelbrot set, color it black.
const ra = require('raster');
// n is the size of the display
let n = 220;
ra.useDips({'x': -0.7, 'y': 0.0, 'z': 2.44});
ra.setSize({w:n, h:n});
ra.setZoom(2);
function drawFractal() {
let [x, y, z] = [ra.dip['x'], ra.dip['y'], ra.dip['z']];
ra.fillFrame((i, j) => {
let u = i - (n / 2);
let v = j - (n / 2);
return converge(x + (u * z / n), y + (v * z / n));
});
}
ra.on('click', (e) => {
let u = (e.x - (n / 2));
let v = (e.y - (n / 2));
ra.setDip('x', ra.dip['x'] + (u * ra.dip['z'] / n));
ra.setDip('y', ra.dip['y'] + (v * ra.dip['z'] / n));
ra.setDip('z', ra.dip['z'] * 0.8);
});
ra.on('dipchange', () => {
drawFractal();
ra.runFrame();
});
drawFractal();
ra.run();
function converge(x, y) {
let initX = x;
let initY = y;
for (let k = 0; k < 60; k++) {
let a = x * x;
let b = x * y;
let c = y * y;
x = a - c + initX;
y = 2 * b + initY;
if (Math.abs(x) > 10 || Math.abs(y) > 10) {
return (k+16)%64;
}
}
return 0;
}