xxxxxxxxxx
146
p5.disableFriendlyErrors = true; //To help speed up the program.
let iter_count;
let slider_x;
let slider_y;
let zoom;
let zoomLevel;
let x;
let y;
let lock;
let lockV;
function setup() {
pixelDensity(1);
createCanvas(400, 400);
background(220);
lockV = false;//LockV switches mouse controls between generating sets, and dragging the view
createP("Click and drag around to generate a Julia Set (based on the veiw window). If you find one you like you can lock it with the button below. This allows you to use the mouse to move around. Click lock again to look for a new set.")
lock = createButton("Lock Set");
lock.mousePressed(switchControl);
zoomLevel = createP("Zoom level: 1.1^-6");
createP("Limit of zoom level is around 1.1^-340")
iter_level = createP("Iteration count: 50");
iter_count = createSlider(5, 700, 50, 5);
createP("Drag the mouse to move around! Scroll wheel to adjust zoom level.");
iter_count.changed(updateIter);
iter = iter_count.value()
zoom = -6;
ZM = 2 - Math.pow(1.1, -zoom)
slider_x = 0;
slider_y = 0;
x = 0;
y = 0;
}
function draw() {
displayM();
}
function displayM() {
loadPixels();
for (let i = 0; i < width; i++) {
for (let j = 0; j < height; j++) {
let id = (i + (j * width)) * 4;
let c = Julia(i, j, x, y);
pixels[id] = c[0];
pixels[id + 1] = c[1];
pixels[id + 2] = c[2];
pixels[id + 3] = c[3];
}
}
updatePixels();
}
function updateIter() {
iter = iter_count.value()
iter_level.html("Iteration count: " + iter);
}
function mouseWheel() {
zoom -= event.delta / 100;
ZM = 2 - Math.pow(1.1, -zoom);
zoomLevel.html("Zoom level: 1.1^" + -zoom);
}
function mouseDragged() {
if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {
if (lockV) {
slider_x -= map(movedX, -width / 2, width / 2, -2 + ZM, 2 - ZM);
slider_y -= map(movedY, -height / 2, height / 2, -2 + ZM, 2 - ZM);//These map the x and y to the current zoom level and adjusts them accordingly, letting you move smoothly at different zoom levels.
} else if (!lockV) {
x = map(mouseX, 0, width, -2 + slider_x + ZM, 2 + slider_x - ZM);
y = map(mouseY, 0, height, -2 + slider_y + ZM, 2 + slider_y - ZM);//Sets the constant for the julia set.
}
}
}
function switchControl() {
lockV = !lockV
}
function Julia(i, j, x, y) {
let zX = map(i, 0, width, -2 + slider_x + ZM, 2 + slider_x - ZM);
let zY = map(j, 0, height, -2 + slider_y + ZM, 2 + slider_y - ZM);//Maps the canvas to the current zoom level/veiw xy
let iteration = iter;
for (let a = 0; a < iter; a++) {
let X = zX * zX - zY * zY;
let Y = 2 * zX * zY;
zX = X + x;
zY = Y + y;
if (abs(zX) >= 3 || abs(zY) >= 2) {
break;
} else {
iteration--
}
}
let c = map(iteration % 100, 0, 100, 0, PI);//The color for the selected pixel, mapped to allow for smoother color transitions
if (0 == iteration) {
return [0, 0, 0, 255];//Paints pixel black if it looks to be convergeing
} else {
return HSVtoRGB(c, 0.9, 1);
}
}
function HSVtoRGB(h, s, v) {
let r, g, b, i, f, p, q, t;
i = floor(h * 6);
f = h * 6 - i;
p = v * (1 - s);
q = v * (1 - f * s);
t = v * (1 - (1 - f) * s);
switch (i % 6) {
case 0: r = v; g = t; b = p; break;
case 1: r = q; g = v; b = p; break;
case 2: r = p; g = v; b = t; break;
case 3: r = p; g = q; b = v; break;
case 4: r = t; g = p; b = v; break;
case 5: r = v; g = p; b = q; break;
}
return [
r * 255,
g * 255,
b * 255,
255
]
}