I decided to attack the problems I was having on my Mystify code with a bit of additional knowledge and finesse while still avoiding any new topics, like multi-dimensional arrays. I came up with a simple solution for the ghost trails by essentially reducing the alpha (i.e. transparency) of the background refresh.

I added a couple of extra flourishes, like a line thickness that adapts to the length of the lines and an additional white halo that helps to separate the various iterations for some extra drama. The line thickness is a logarithmic function of the distance between the two endpoints, so it has a lot of contrast at the shorter distances but approaches a set limit on the longer ones.

See the posted code below:

let x = []; let y = []; let s = 5; let dX = []; let dY = []; let bounceX = []; let bounceY = []; let p = 5; let i = 0; let c = 0; let bounceC = true; function setup() { createCanvas(400, 400); background(255); for (i = 0; i < p; i += 1) { x[i] = width / 2; y[i] = height / 2; dX[i] = random(s); dY[i] = sqrt(pow(s, 2) - pow(dX[i], 2)); } } function draw() { background(255, 2); stroke(255); for (i = 0; i < p; i += 1) { strokeWeight(1.05 * log(sqrt(pow(x[i] - x[(i + 1) % p], 2) + pow(y[i] - y[(i + 1) % p], 2)) + 2) * 4); line(x[i], y[i], x[(i + 1) % p], y[(i + 1) % p]); } stroke(35, c / 2, 255 - c / 3); for (i = 0; i < p; i += 1) { strokeWeight(log(sqrt(pow(x[i] - x[(i + 1) % p], 2) + pow(y[i] - y[(i + 1) % p], 2)) + 2) * 4); line(x[i], y[i], x[(i + 1) % p], y[(i + 1) % p]); } for (i = 0; i < p; i += 1) { if (x[i] > width) { bounceX[i] = true; } if (x[i] < 0) { bounceX[i] = false; } if (y[i] > height) { bounceY[i] = true; } if (y[i] < 0) { bounceY[i] = false; } if (bounceX[i] == true) { x[i] = x[i] - dX[i]; } else { x[i] = x[i] + dX[i]; } if (bounceY[i] == true) { y[i] = y[i] - dY[i]; } else { y[i] = y[i] + dY[i]; } } if (c > 255) { bounceC = false; } if (c < 0) { bounceC = true; } if (bounceC == true) { c += 1; } if (bounceC == false) { c -= 1; } }