The mandelbrot algorithm in SCSS. rendering the mandelbrot set in one element
<mandelbrot-set></mandelbrot-set>
A Live example by Gregor Adams
mandelbrot-set |
The mandelbrot algorithm in SCSS. rendering the mandelbrot set in one element
<mandelbrot-set></mandelbrot-set>
A Live example by Gregor Adams
/** | |
* @doc settings | |
*/ | |
// 50 * 15 takes about 6 minutes to compile, so be careful how high you set these. | |
// this might end up crashing | |
$factor: 50; | |
$iterations: 15; // number of shading iterations | |
$pixel-size: 1px; // size of one point | |
$color-step: 20; // hue-roatation per iteration | |
$color-start: 0; // hue starting point | |
////////////////////////////// | |
// don’t edit beyond this part | |
//// ////////////////////// // | |
/// ////////////////////// /// | |
// ////////////////////// //// | |
/** | |
* @doc variables | |
*/ | |
$start: -2; | |
$end: 2; | |
$xx: 0; | |
$yy: 0; | |
$next: (); | |
$shadow: (); | |
/** | |
* @doc functions | |
*/ | |
@function square($n) { | |
@return $n * $n; | |
} | |
@function complex-add($x, $y) { | |
@return square($y) + square($x); | |
} | |
@function complex-subtract($x, $y) { | |
@return square($x) - square($y); | |
} | |
@function complex-multiply($x, $y) { | |
@return 2 * $x * $y; | |
} | |
@function complex-next($z) { | |
$x: nth($z, 1); | |
$y: nth($z, 2); | |
$a: complex-subtract($x, $y) + $xx; | |
$b: complex-multiply($x, $y) + $yy; | |
$ret: complex-add($a, $b); | |
@return $a, $b, $ret; | |
} | |
/** | |
* @doc Mandelbrot set | |
* | |
* @description | |
* renders the Mandelbrot set | |
*/ | |
@for $x from $start * $factor through $end * $factor { | |
@for $y from $start * $factor through $end * $factor { | |
// resolve positions | |
$xx: $x / $factor !global; | |
$yy: $y / $factor !global; | |
// flag to make sure we know when to stop | |
$done: false; | |
// first match | |
$first: complex-add($xx, $yy); | |
// next match | |
$next: ($xx, $yy)!global; | |
// paint the squares | |
$h: 0; | |
$s: 100; | |
$l: 50; | |
$sx: $x*1px; | |
$sy: $y*1px; | |
@if $first > 4 { // try the first iteration | |
@if $done == false { | |
$h: $color-start; | |
$done: true; | |
} | |
} @else { // then try the rest of the iterations | |
@for $i from 2 through $iterations { | |
// calculate the next complex number | |
$next: complex-next($next)!global; | |
@if $i % 2 == 0 { // even numbers refer to 2 | |
// still bigger than 2? | |
@if nth($next, 3) > 2 { | |
@if $done == false { | |
$h: ($i - 1) * $color-step + $color-start; | |
$done: true; | |
} | |
} | |
} @else { // odd numbers refer to 4 | |
// still bigger than 4? | |
@if nth($next, 3) > 4 { | |
@if $done == false { | |
$h: ($i - 1) * $color-step + $color-start; | |
$done: true; | |
} | |
} | |
} | |
} | |
} | |
@if $done == false { // still no match? paint black | |
$l: 0; | |
$done: true; | |
} | |
// set the color with the calculated values | |
$sh: '#{$x*$pixel-size} #{$y*$pixel-size} 0 hsl(#{$h},#{$s},#{$l})'; | |
$shadow: join($shadow, unquote($sh), comma)!global; | |
} | |
} | |
mandelbrot-set { | |
margin: $pixel-size*$factor*2; | |
display: block; | |
width: $pixel-size; | |
height: $pixel-size; | |
background: #000; | |
box-shadow: unquote($shadow); | |
} |