Skip to content

Instantly share code, notes, and snippets.

@blinsay
Forked from d2fn/README.md
Last active August 29, 2015 14:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save blinsay/c799e19d06baef776b5e to your computer and use it in GitHub Desktop.
Save blinsay/c799e19d06baef776b5e to your computer and use it in GitHub Desktop.
Gradient Descent

Gradient descent on 2d Perlin noise. Inspired by and forked from d2fn

<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
background: rgb(255, 255, 255);
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="/d2fn/raw/8777d620caef32959713/perlin.js"></script>
<script>
var width = 960,
height = 500,
noiseScale = 0.003,
actorStepLength = 1000,
numActors = 10000,
step = 0,
steps = 150,
gradientEpsilon = noiseScale / 100.0;
var canvas = d3.select("body")
.append("canvas")
.attr({width: width, height: height});
var context = canvas.node().getContext("2d");
context.fillStyle = "rgb(0, 0, 0)";
context.fillRect(-1, -1, width, height);
var actors = [];
for(var i = 0; i < numActors; i++) {
actors.push(actor(width, height, noiseScale, actorStepLength));
}
var opacity = easeInOut(steps);
d3.timer(function() {
if(++step > steps) {
console.log("done with animation");
return true;
}
context.lineWidth = 1;
context.globalCompositeOperation = 'lighter';
context.beginPath();
for(var i in actors) {
var a = actors[i];
var ln = a.step();
var alpha = 0.6*opacity.get();
context.strokeStyle = "rgba(49, 130, 189, " + alpha + ")";
context.moveTo(ln.x1, ln.y1);
context.lineTo(ln.x2, ln.y2);
}
context.stroke();
opacity.step();
});
function actor(width, height, noiseScale, stepLength) {
var x = Math.random() * width,
y = Math.random() * height;
var noise = perlin.noise(noiseScale);
return {
// get the last point and the next point
step: function() {
var x1 = x,
y1 = y,
grad = approximateGradient(noise, x, y, gradientEpsilon);
x = x + stepLength * (-1 * grad.x),
y = y + stepLength * (-1 * grad.y);
return {
x1: x1,
y1: y1,
x2: x,
y2: y
}
}
}
}
function easeInOut(steps) {
var n = 0;
var val = 0;
return {
step:
function() {
val = 0.075*(1-Math.cos(2 * Math.PI * (n++) / steps));
},
get:
function() {
return val;
}
};
}
function approximateGradient(f, x, y, h) {
return {
x: (f(x + h, y) - f(x - h, y)) / (2*h),
y: (f(x, y + h) - f(x, y - h)) / (2*h)
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment