xxxxxxxxxx
99
// First attempt at a Mandelbrot set for years.
// G Edwards, gedwards2@gmail.com, 21 Feb 2020
// Start at 7.30
// 8.30 - first recognizable Mandelbrot ! after about 200 errors
// 9.30 - got it tidy enough to publish
let Width = 1000; // size of drawing area
let Height = 750;
let maxIter = 80; // max steps to run the Mandelbrot iteration
// Standard Processing / p5.js setup function. This is run once by the p5 framework.
function setup() {
createCanvas(Width, Height);
}
// Standard p5.js drawing function. This is run repeatedly by the p5 framework.
function draw() {
for(let i = 0; i < Width; i++) { // loop over the columns of the canvas
let ci = 0.8 + (i - Width / 2) / 400; // i part of complex(i,j). The 0.8 shifts it to a good position.
if(i%100 === 0) prt("column", i, ", x value", ci.toFixed(2)); // some feedback in console
for(let j = 0; j < Height; j++) { // loop over rows of the canvas
let cj = (j - Height / 2) / 400; // j part of complex(i,j)
let result = iterate(ci, cj);
if( result < maxIter) stroke(color(255)); // black
else stroke(0); // white
point(i, j); // one pixel
// Check points are really 1 pixel
// if((i % 10) === 0 && (j % 10) === 0) stroke(255,0,0), point(i, j);
}
}
prt("Done");
noLoop(); // stop the repetitive running of draw()
}
// The key maths. We don't have a standard complex lib in JavaScript or p5.js, just do it by hand with the i, j values.
function iterate(ci, cj) {
let zi = 0; // Start the iteration with z = (0, 0).
let zj = 0;
let n = 0;
// while (complexAbs(zi, zj) <= 2 && n < maxIter) { // Don't need this, sqrt is expensive, just test against the square
while ( ((zi * zi) + (zj * zj) ) <= 4 && n < maxIter) {
let znew = product(zi, zj, zi, zj);
zi = znew[0] - ci;
zj = znew[1] - cj;
n += 1;
}
return n;
}
// Don't need to use this. Just test the square.
function complexAbs(i, j) {
return sqrt(i * i + j * j);
}
// The old familiar complex product ! Learned this in about Year 11 or 12 high school.
function product(i1, j1, i2, j2) {
let pi = (i1 * i1) - (j1 * j2);
let pj = (i1 * j2) + (j2 * i1);
return [pi, pj]; // return an array
}
// Convenience interlude - console.log() is tedious to type.
function prt(args) {
console.log(args);
}