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" | |
] | |
} |
<style>body{background:#000}/*make background black(it's just for the looks)*/</style> | |
<canvas id=canvas width=512 height=512></canvas> | |
<script> | |
var mandelbrot = 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} | |
var ctx = document.getElementById('canvas').getContext('2d'); | |
var imgd = ctx.createImageData(512,512); | |
var pix = imgd.data; | |
for(i=512*512*4;i--;)pix[i]=256 //make canvas white (it's just for the looks) | |
mandelbrot(pix,512); | |
ctx.putImageData(imgd,0,0); | |
</script> |
@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!
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
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.
@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!
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!
@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!
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.
oups...
https://gist.github.com/1261166 the classic Mandelbrot set, in 140 bytes
https://gist.github.com/1267983 with panning and zooming, in 133 bytes ;)
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 tow*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?