Little experiment with fractals. One day I founded the Mandelbrot's algorithm and I wanted to play with. Now it is written with d3 painting on canvas, pixel to pixel. Maybe I will try others implementations to improve performance.
Last active
November 21, 2016 06:27
-
-
Save proclamo-zz/bd38273f0d72dce46b6f to your computer and use it in GitHub Desktop.
d3.js Mandelbrot's fractal experiment
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title></title> | |
<style type="text/css"> | |
.info { | |
color: red; | |
padding: 3px; | |
position: absolute; | |
top: 10px; | |
left: 10px; | |
} | |
.info:hover { | |
background-color: rgba(255, 255, 255, .7); | |
border-radius: 5px; | |
} | |
.msg { | |
text-align: left; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="info"></div> | |
<div class="container"></div> | |
<div class="msg"> | |
Click for zoom In | |
</div> | |
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script> | |
<script type="text/javascript"> | |
(function() { | |
var width = 533, | |
height = 400, | |
iterations = 150, | |
radious = 2, | |
factor = 2, | |
step = 1, | |
x1 = -1.7, | |
y1 = -1, | |
x2 = 1, | |
y2 = 1, | |
bounds | |
; | |
var color = d3.scale.category20c(); | |
var canvas = d3.select(".container") | |
.append("canvas") | |
.attr({width: width, height: height}) | |
.on("click", clicked) | |
.node().getContext("2d"); | |
var center = [width / 2, height / 2]; | |
rescale(); | |
calculateBounds(center); | |
draw(); | |
function calculateBounds(center) { | |
var p = [center[0] - (width / factor), center[1] - (height / factor), center[0] + (width / factor), center[1] + (height / factor)]; | |
x1 = x(p[0]); | |
y1 = y(p[1]); | |
x2 = x(p[2]); | |
y2 = y(p[3]); | |
} | |
function rescale() { | |
bounds = [x1, x2, y1, y2]; | |
x = d3.scale.linear() | |
.domain([0, width]) | |
.range([bounds[0], bounds[1]]); | |
y = d3.scale.linear() | |
.domain([0, height]) | |
.range([bounds[2], bounds[3]]); | |
} | |
function clicked() { | |
var center = [d3.event.x, d3.event.y]; | |
/* zoom out (Shift + click) but it has bugs | |
if (d3.event.shiftKey) { | |
factor -= .2; | |
} | |
else { | |
factor += .2; | |
} | |
*/ | |
factor += .2; // zomIn | |
factor = Math.round(factor * 10) / 10; | |
calculateBounds(center); | |
rescale(); | |
draw(); | |
} | |
function draw() { | |
canvas.fillStyle = "rgb(0, 0, 0)"; | |
canvas.fillRect(-1, -1, width, height); | |
mandelbrot(); | |
showInfo(); | |
} | |
function mandelbrot() { | |
var p0, q0, z, esc, _x, _y; | |
var dp = (x2 - x1)/(width - 1); | |
var dq = (y2 - y1)/(height - 1); | |
for (var i = 0; i < width; i += step) { | |
for (var j = 0; j < height; j += step) { | |
p0 = x1 + i * dp; | |
q0 = y1 + j * dq; | |
z = { re: p0, im: q0 }; | |
c = z; | |
esc = 0; | |
for (var k = 1; k < iterations; k++) { | |
_x = z.re * z.re - z.im * z.im + c.re; | |
_y = 2 * z.re * z.im + c.im; | |
z = { re: _x, im: _y }; | |
esc++; | |
if (Math.sqrt(Math.pow(z.re, 2) + Math.pow(z.im, 2)) > radious) { | |
canvas.fillStyle = color(esc); | |
canvas.fillRect(i, j, step, step); | |
break; | |
} | |
} | |
} | |
} | |
} | |
function showInfo() { | |
d3.select(".info") | |
.text("Zoom: " + factor + "x"); | |
} | |
})(); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment