Skip to content

Instantly share code, notes, and snippets.

@joyrexus
Last active December 25, 2015 00:39
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 joyrexus/6889658 to your computer and use it in GitHub Desktop.
Save joyrexus/6889658 to your computer and use it in GitHub Desktop.
Nonlinear anecdote

Extraction/conversion of a plotting visualization -- the nonlinear anecdote -- from @worrydream's Kill Math noodlings.

See also Evan Miller's response, Don't Kill Math.

<!DOCTYPE html>
<meta charset="utf-8">
<script src="lib.js"></script>
<body>
<canvas id="Nonlinear" width="240" height="240"></canvas>
<script>
var canvas = document.getElementById('Nonlinear');
viz = new Nonlinear(canvas);
setInterval(viz.updateAnimation, 20);
</script>
class Nonlinear
constructor: (canvas) ->
@canvas = @element = canvas
@width = parseInt(canvas.width)
@height = parseInt(canvas.height)
@ctx = @canvas.getContext("2d")
@plotScale = 50
@plotOffsetX = @width/2
@plotOffsetY = @height/2
@timeStep = 10e-3
@hasReset = false
@backgroundImage = new Image()
@backgroundImage.src = "background.png"
updateAnimation: =>
now = Date.now()
dt = 0.001 * (now - (@lastTimestamp || now))
@lastTimestamp = now
return null if dt is 0
@reset() if not @hasReset
@currentTime += dt
@currentTimeModStep += dt
while @currentTimeModStep > @timeStep
@currentTimeModStep -= @timeStep
@tick(@timeStep)
@drawInContext(@ctx)
@reset() if @currentTime > 18
reset: () =>
@hasReset = true
@currentTime = 0
@currentTimeModStep = 0
@x = -1
@y = 0
@ctx.drawImage(@backgroundImage, 0, 0)
@ctx.closePath()
@ctx.lineWidth = 1
@ctx.strokeStyle = "#2392d9"
@ctx.beginPath()
@ctx.moveTo(@x * @plotScale + @plotOffsetX, -@y * @plotScale + @plotOffsetY)
tick: (dt) =>
dx = dt * @y
dy = dt * (-0.5 * @y - 5 * Math.sin(@x))
@x += dx
@y += dy
@ctx.lineTo(@x * @plotScale + @plotOffsetX, -@y * @plotScale + @plotOffsetY)
drawInContext: (ctx) =>
ctx.stroke()
ctx.closePath()
ctx.beginPath()
ctx.moveTo(@x * @plotScale + @plotOffsetX, -@y * @plotScale + @plotOffsetY)
window.Nonlinear = Nonlinear
// Generated by CoffeeScript 1.6.3
(function() {
var Nonlinear,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
Nonlinear = (function() {
function Nonlinear(canvas) {
this.drawInContext = __bind(this.drawInContext, this);
this.tick = __bind(this.tick, this);
this.reset = __bind(this.reset, this);
this.updateAnimation = __bind(this.updateAnimation, this);
this.canvas = this.element = canvas;
this.width = parseInt(canvas.width);
this.height = parseInt(canvas.height);
this.ctx = this.canvas.getContext("2d");
this.plotScale = 50;
this.plotOffsetX = this.width / 2;
this.plotOffsetY = this.height / 2;
this.timeStep = 10e-3;
this.hasReset = false;
this.backgroundImage = new Image();
this.backgroundImage.src = "background.png";
}
Nonlinear.prototype.updateAnimation = function() {
var dt, now;
now = Date.now();
dt = 0.001 * (now - (this.lastTimestamp || now));
this.lastTimestamp = now;
if (dt === 0) {
return null;
}
if (!this.hasReset) {
this.reset();
}
this.currentTime += dt;
this.currentTimeModStep += dt;
while (this.currentTimeModStep > this.timeStep) {
this.currentTimeModStep -= this.timeStep;
this.tick(this.timeStep);
}
this.drawInContext(this.ctx);
if (this.currentTime > 18) {
return this.reset();
}
};
Nonlinear.prototype.reset = function() {
this.hasReset = true;
this.currentTime = 0;
this.currentTimeModStep = 0;
this.x = -1;
this.y = 0;
this.ctx.drawImage(this.backgroundImage, 0, 0);
this.ctx.closePath();
this.ctx.lineWidth = 1;
this.ctx.strokeStyle = "#2392d9";
this.ctx.beginPath();
return this.ctx.moveTo(this.x * this.plotScale + this.plotOffsetX, -this.y * this.plotScale + this.plotOffsetY);
};
Nonlinear.prototype.tick = function(dt) {
var dx, dy;
dx = dt * this.y;
dy = dt * (-0.5 * this.y - 5 * Math.sin(this.x));
this.x += dx;
this.y += dy;
return this.ctx.lineTo(this.x * this.plotScale + this.plotOffsetX, -this.y * this.plotScale + this.plotOffsetY);
};
Nonlinear.prototype.drawInContext = function(ctx) {
ctx.stroke();
ctx.closePath();
ctx.beginPath();
return ctx.moveTo(this.x * this.plotScale + this.plotOffsetX, -this.y * this.plotScale + this.plotOffsetY);
};
return Nonlinear;
})();
window.Nonlinear = Nonlinear;
}).call(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment