lambdaway
::
mandel_canvas
6
|
list
|
login
|
load
|
|
_h1 [[mandel|?view=mandelbrot]]{sup {sup interactive}} | mandel{sup {sup made easy}} _ul [[http://www.rosettacode.org/wiki/Mandelbrot_set|http://www.rosettacode.org/wiki/Mandelbrot_set]]. {macro \/\/ ([^\n]*)\n to
// $1
} _h2 1) lambdatalk only _p A slow but minimalistic and {b easy to understand version} of the mandelbrot set algorithm, without the burden of any canvas. We {i just} compute if a point is inside or outside the mandelbrot set and {i just} write "{b o}" or "{b .}" directly in the wiki page. {pre '{def mandel {def mandel.r {lambda {:iter :cx :cy :norm :x :y :count} {if {> :count :iter} // then norm < 4 then // inside the set let's plot "o" {span {@ style="color:rgb({% {* 10 255 :norm} 255}, 0,0);"}o} else {if {> :norm 4} // then iter > max then // outside the set let's plot "." {span {@ style="color:rgb(0,{* 255 {/ {log :count} {log {- :iter 1}}}}, 0);"}.} else {let { {:cx :cx} {:cy :cy} {:iter :iter} // remember... {:X {+ {* :x :x} -{* :y :y} :cx}} // compute {:Y {+ {* 2 :x :y} :cy}} // z = z^2+c {:count {+ :count 1}} } {mandel.r :iter :cx :cy // unchanged {+ {* :X :X} {* :Y :Y}} // new norm :X :Y // new x & y :count} }}}}} // next count {lambda {:iter :cx :cy} {mandel.r :iter {+ {* :cx 0.05} -1.50} // centering the set {+ {* :cy 0.05} -0.75} // inside the frame 0 0 0 0} }} -> {def mandel {def mandel.r {lambda {:iter :cx :cy :norm :x :y :count} {if {> :count :iter} then {span {@ style="color:rgb({% {* 10 255 :norm} 255}, 0,0);"}o} else {if {> :norm 4} then {span {@ style="color:rgb(0,{* 255 {/ {log :count} {log {- :iter 1}}}}, 0);"}.} else {let { {:cx :cx} {:cy :cy} {:iter :iter} {:X {+ {* :x :x} -{* :y :y} :cx}} {:Y {+ {* 2 :x :y} :cy}} {:count {+ :count 1}} } {mandel.r :iter :cx :cy {+ {* :X :X} {* :Y :Y}} :X :Y :count} }}}}} {lambda {:iter :cx :cy} {mandel.r :iter {+ {* :cx 0.05} -1.50} {+ {* :cy 0.05} -0.75} 0 0 0 0} }} } _p We call {b mandel} directly in the wiki page {pre '{S.map {lambda {:i} {br} // loop on y {S.map {{lambda {:i :j} // loop on x {mandel 20 :i :j}} :i} // compute with iter=20 {S.serie 0 30}}} // x resolution {S.serie 0 40}} // y resolution -> {S.map {lambda {:i}
{S.map {{lambda {:i :j} {mandel 20 :i :j}} :i} {S.serie 0 30}}} {S.serie 0 40}} } _h2 2) javascript and canvas _p When time matters ... and colors are required lambdatalk can call javascript. {script function mandelIter(cx, cy, maxIter) { var x = 0.0; var y = 0.0; var xx = 0; var yy = 0; var xy = 0; var i = maxIter; while (i-- && xx + yy <= 4) { xy = x * y; xx = x * x; yy = y * y; x = xx - yy + cx; y = xy + xy + cy; } return maxIter - i; } function color(c, pix, ppos) { if (c < 1) { pix[ppos] = 255 * c; pix[ppos + 1] = 0; pix[ppos + 2] = 0; } else if ( c < 2 ) { pix[ppos] = 255; pix[ppos + 1] = 255 * (c - 1); pix[ppos + 2] = 0; } else { pix[ppos] = 255; pix[ppos + 1] = 255; pix[ppos + 2] = 255 * (c - 2); } } function mandelbrot(canvas, iterations) { var can = document.getElementById(canvas); var width = can.width; var height = can.height; var ctx = can.getContext('2d'); var img = ctx.getImageData(0, 0, width, height); var pix = img.data; for (var ix = 0; ix < width; ++ix) { for (var iy = 0; iy < height; ++iy) { var x = 2 * ix / (width - 1) - 1.5; var y = 2 * iy / (height - 1) -1; var i = mandelIter(x, y, iterations); var ppos = 4 * (width * iy + ix); if (i > iterations) { pix[ppos] = 0; pix[ppos + 1] = 0; pix[ppos + 2] = 0; } else { color( 3 * Math.log(i) / Math.log(iterations - 1.0), pix, ppos) } pix[ppos + 3] = 255; } } ctx.putImageData(img, 0, 0); } setTimeout( function() { mandelbrot("canvas", 1000) }, 1 ) } {canvas {@ id="canvas" width="580" height="580"}} _h2 code {pre °° function mandelIter(cx, cy, maxIter) { var x = 0.0; var y = 0.0; var xx = 0; var yy = 0; var xy = 0; var i = maxIter; while (i-- && xx + yy <= 4) { xy = x * y; xx = x * x; yy = y * y; x = xx - yy + cx; y = xy + xy + cy; } return maxIter - i; } function color(c, pix, ppos) { if (c < 1) { pix[ppos] = 255 * c; pix[ppos + 1] = 0; pix[ppos + 2] = 0; } else if ( c < 2 ) { pix[ppos] = 255; pix[ppos + 1] = 255 * (c - 1); pix[ppos + 2] = 0; } else { pix[ppos] = 255; pix[ppos + 1] = 255; pix[ppos + 2] = 255 * (c - 2); } } function mandelbrot(canvas, iterations) { var can = document.getElementById(canvas); var width = can.width; var height = can.height; var ctx = can.getContext('2d'); var img = ctx.getImageData(0, 0, width, height); var pix = img.data; for (var ix = 0; ix < width; ++ix) { for (var iy = 0; iy < height; ++iy) { var x = 2 * ix / (width - 1) - 1.5; var y = 2 * iy / (height - 1) -1; var i = mandelIter(x, y, iterations); var ppos = 4 * (width * iy + ix); if (i > iterations) { pix[ppos] = 0; pix[ppos + 1] = 0; pix[ppos + 2] = 0; } else { color( 3 * Math.log(i) / Math.log(iterations - 1.0), pix, ppos) } pix[ppos + 3] = 255; } } ctx.putImageData(img, 0, 0); } setTimeout( function() { mandelbrot("canvas", 1000) }, 1 ) °°} _p Lambdatalk and javascript codes are evaluated in realtime, about 1 second. _p You could have a look to this small [[interactive version|?view=mandelbrot]]. {style body, #page_frame, #page_content, .page_menu, pre { background:#444; color:#fff; border:0 #444; box-shadow:0 0 0 #444; } }
lambdaway v.20211111