Skip to content

Instantly share code, notes, and snippets.

@martian17
Created October 7, 2022 05:10
Show Gist options
  • Save martian17/2ce071835a57455819dfef83630f965a to your computer and use it in GitHub Desktop.
Save martian17/2ce071835a57455819dfef83630f965a to your computer and use it in GitHub Desktop.
draws rotated mandelbrot
let width = 1500;
let height = 1500;
let canvas = document.createElement("canvas");
document.body.innerHTML = "";
document.body.appendChild(canvas);
canvas.width = width;
canvas.height = height;
let ctx = canvas.getContext("2d");
let imgdata = ctx.getImageData(0,0,width,height);
let data = imgdata.data;//data buffer array
function flushPixels(){
ctx.putImageData(imgdata,0,0);
}
function getDepth(r0,i0){
let r = r0;
let i = i0;
for (let depth = 0; depth < 260; depth++) {
//exit condition: absolute value
//of the complex number exceeds four
if(r*r+i*i > 4){
//if(r > 200){
return depth;
}
[r,i] = [r*r-i*i + r0, 2*r*i + i0];
}
return -1;
}
function putColor(x,y,r,g,b,a){
let index = (y*canvas.width+x)*4;
data[index+0] = r;
data[index+1] = g;
data[index+2] = b;
data[index+3] = a;
}
function toComplex(x,y,cr,ci,range){
//rx is in range -0.5 to 0.5
//ry is proportional to rx
[x,y] = [y,x];
let [h,w] = [width,height]
let rx = (x-w/2)/width;
let ry = (y-h/2)/width;
return [cr+rx*range,ci+ry*range];
}
function toColor(d){
if(d === -1){
return [0,0,0,255];
}else{
return [d*3,d,d*0.5,255];
}
}
async function render(cr,ci,range){
//center point in imaginary and complex
//range signifies the span of the canvas
//on the underlying coordinate system
let cnt = 0;
let interval = 10000;//render every 100 pixel
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
//sub pixel sampling
let depth =
(getDepth(...toComplex(x-1/3,y-1/3,cr,ci,range))+
getDepth(...toComplex(x-1/3,y+1/3,cr,ci,range))+
getDepth(...toComplex(x+1/3,y-1/3,cr,ci,range))+
getDepth(...toComplex(x+1/3,y+1/3,cr,ci,range)))/4;
(toColor(depth));
putColor(x,y,...toColor(depth));
cnt++;
if(cnt%interval === 0){
console.log(`${Math.floor(cnt/(width*height)*10000)/100}%`);
flushPixels();
await new Promise(res=>setTimeout(res,0));
}
}
}
}
render(-0.5,0,3);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment