Instantly share code, notes, and snippets.

Draw mandelbrot fractal on canvas

Draws a mandelbrot fractal on a canvas.

usage:

mandelbrot(imageData,width)

Thanks to @atk for doing most of the minification work!

 //version 2.0 (using alpha instead of color!) function(d,w,x,y,a,b,e,f,i,q,z){ for(b=w;b--;y=3*b/w-1.5) for(a=w;a--;e=x=3*a/w-2,f=y) { for(i=256;i--&&e*e+f*f<4;)q=e*e-f*f+x,f=2*e*f+y,e=q; this[d][(w*b+a<<2)+3]=255-(i%8*32); } } //version 2.1 function(d,w,x,y,a,b,e,f,i,q){ for(b=w;b--;y=3*b/w-1.5) for(a=w;a--;e=x=3*a/w-2,f=y) { for(i=256;i--&&e*e+f*f<4;e=q)q=e*e-f*f+x,f=2*e*f+y; this[d][(w*b+a<<2)+3]=255-i%8*32; } } //version 3.0 (Thanks @atk!) function(d,w,x,y,a,b,e,f,i,q){ for(b=w;b--;y=3*b/w-1.5) for(a=w;a--;d[(w*b+a<<2)+3]=255-i%8*32,e=x=3*a/w-2,f=y) for(i=256;i--&&e*e+f*f<4;e=q)q=e*e-f*f+x,f=2*e*f+y } //version 4.0 (Thanks again @atk!) function(d,w,x,y,a,b,e,f,i,q){ for(b=w;b--;y=4*b/w-2) for(a=w;a--;d[(w*b+a)*4+3]=i%8*32,e=x=4*a/w-2,f=y) for(i=256;q=f*f,i--&&e*e+q<4;e=e*e-q+x)f=2*e*f+y } //version 5.0 (137 bytes)(@atk is an absolute boss!) function(d,w,x,y,a,e,f,i,q){for(a=w*w;a--;d[a*4+3]=i%8*32,e=x=4*(a%w)/w-2,f=y=4*a/w/w-2)for(i=256;q=f*f,i--&&e*e+q<4;e=e*e-q+x)f=2*e*f+y} //version 6.0 (115 bytes =D ) function(d,w,a,e,f,i,q){for(a=w*w*4;a-=4;d[a+3]=i%8*32)for(e=f=0,i=256;--i/e;f=q)q=2*e*f+a/w/w-2,e=e*e-f*f+a/w%4-2} //version 6.1 (137 bytes) simpler syntax: mandelbrot(imageData) function(d,w,a,e,f,i,q){for(w=Math.sqrt((a=pix.length)/4);a-=4;d[a+3]=i%8*32)for(e=f=0,i=256;--i/e;f=q)q=2*e*f+a/w/w-2,e=e*e-f*f+a/w%4-2}
 function(d,w,a,e,f,i,q){for(a=w*w*4;a-=4;d[a+3]=i%8*32)for(e=f=0,i=256;--i/e;f=q)q=2*e*f+a/w/w-2,e=e*e-f*f+a/w%4-2}
 { "name": "drawMandelbrot", "description": "Draws a mandelbrot fractal on a canvas.", "keywords": [ "Mandelbrot", "fractal", "canvas", "math" ] }


### atk commented Apr 10, 2012

 replace a<<2 with a*4, save one byte; instead of using this[d], give the imageData directly to the function, save 6 more bytes: `function(d,w,x,y,a,b,e,f,i,q){for(b=w;b--;y=3*b/w-1.5)for(a=w;a--;e=x=3*a/w-2,f=y){for(i=256;i--&&e*e+f*f<4;e=q)q=e*e-f*f+x,f=2*e*f+y;d[(w*b+a*4)+3]=255-i%8*32;}}` Update: save 2 more bytes by rewiring what comes after the last for loop into the second loop's after-statement: `function(d,w,x,y,a,b,e,f,i,q){for(b=w;b--;y=3*b/w-1.5)for(a=w;a--;d[(w*b+a*4)+3]=255-i%8*32,e=x=3*a/w-2,f=y)for(i=256;i--&&e*e+f*f<4;e=q)q=e*e-f*f+x,f=2*e*f+y}` Another update: due to operator precedence, `(w*b+a*4)+3` can be shortened to `w*b+a*4+3`, saving another 2 bytes (17 to go): `function(d,w,x,y,a,b,e,f,i,q){for(b=w;b--;y=3*b/w-1.5)for(a=w;a--;d[w*b+a*4+3]=255-i%8*32,e=x=3*a/w-2,f=y)for(i=256;i--&&e*e+f*f<4;e=q)q=e*e-f*f+x,f=2*e*f+y}` By the way, would you mind filling out the package.json?
Owner Author

### williammalo commented Apr 10, 2012

 @atk quote:"replace a<<2 with a_4" It doesn't work, because "_" and "<<" don't have the same operator precedence. Thanks for the other tricks tho!

### atk commented Apr 10, 2012

 The last loop could be reduced by 2 bytes if we use q to store f*f instead of what later becomes e: before: `for(i=256;i--&&e*e+f*f<4;e=q)q=e*e-f*f+x,f=2*e*f+y` after: `for(i=256;q=f*f,i--&&e*e+q<4;e=e*e-q+x)f=2*e*f+y`

### atk commented Apr 10, 2012

 btw. you are aware that i%8_32 will be the same as i%256 (you probably intended (i%8)_32 or you need to expand one more byte to use i%8<<5 instead. Anyway, the 255-i%256 is obviously used to invert the fractal; as much as it is probably visually pleasing, maybe we can lose the inverting in order to get closer to 140bytes. And thank you for updating the package.json Update: you forgot to remove one of the closing curly brackets in your version 3.0.
Owner Author

### williammalo commented Apr 10, 2012

 @atk I%8*32 is not the same as i%256, again because of operator precedence. Yeah, the inverting is indeed useless, I removed it!

### atk commented Apr 10, 2012

 Oh, just found an error in the operator precedence chart from mozilla :-) What do you think, would we save bytes if we joined the first two loops into one by counting from w*w to 0? Update: Got it: `function(d,w,x,y,a,e,f,i,q){for(a=w*w;a--;d[a*4+3]=i%8*32,e=x=4*(a%w)/w-2,f=y=4*a/w/w-2)for(i=256;q=f*f,i--&&e*e+q<4;e=e*e-q+x)f=2*e*f+y}` 137bytes! Glad to have been your caddy on this golf course!
Owner Author

### williammalo commented Apr 10, 2012

 @atk Thats funny, I actually use the mozilla chart for operator precedence. =D yay for <140 bytes! I actually had the same idea but the code failed every time I tried, so I figured it wouldn't work. You are a boss!

### atk commented Apr 11, 2012

 Just one minor update: // is not a valid comment in css. In addition, I would put the background to the canvas element - the page looks better this way.
Owner Author

### williammalo commented Apr 11, 2012

 @atk oups...

### p01 commented Apr 11, 2012

 https://gist.github.com/1261166 the classic Mandelbrot set, in 140 bytes https://gist.github.com/1267983 with panning and zooming, in 133 bytes ;)