Skip to content

Instantly share code, notes, and snippets.

@nikcorg
Created April 6, 2012 22:08
Show Gist options
  • Save nikcorg/2323429 to your computer and use it in GitHub Desktop.
Save nikcorg/2323429 to your computer and use it in GitHub Desktop.
Bresenham's line algorithm
/**
* My take on Bresenham's line algorithm
*
* http://en.wikipedia.org/wiki/Bresenham's_line_algorithm
*
* Based off of the limited algorithm, amended by own research,
* trial and error, and plain stubborness.
*
* Demo: http://jsfiddle.net/VFybR/26/
*/
var Point = function (x, y) {
this.x = x;
this.y = y;
};
Point.prototype.x = 0;
Point.prototype.y = 0;
var Stage = function (canvas) {
this.canvas = canvas;
this.context = this.canvas.getContext("2d");
this.width = this.canvas.width;
this.height = this.canvas.height;
this.clear();
};
Stage.prototype.canvas = null;
Stage.prototype.context = null;
Stage.prototype.width = 0;
Stage.prototype.height = 0;
Stage.prototype.color = "#000";
Stage.prototype.clear = function () {
this.context.clearRect(0, 0, this.width, this.height);
this.context.strokeStyle = this.color;
this.context.strokeRect(1, 1, this.width - 2, this.height - 2);
};
Stage.prototype.drawLine = function (from, to) {
var deltaX = to.x - from.x;
var deltaY = to.y - from.y;
var stepX = Math.min(1.0, Math.abs(deltaX / deltaY) || 0);
var stepY = Math.min(1.0, Math.abs(deltaY / deltaX) || 0);
var signDX = -1 * (deltaX / -Math.abs(deltaX)) || 1;
var signDY = -1 * (deltaY / -Math.abs(deltaY)) || 1;
var untilX = from.x * signDX + deltaX * signDX;
var untilY = from.y * signDY + deltaY * signDY;
var pos = new Point(from.x, from.y);
var eX = 0;
var eY = 0;
while (
(pos.x * signDX < untilX) ||
(pos.y * signDY < untilY)
) {
this.plot(pos);
eX += stepX * signDX;
if (Math.abs(eX) > 0.5) {
pos.x += signDX;
eX += 1.0 * -signDX;
}
eY += stepY * signDY;
if (Math.abs(eY) > 0.5) {
pos.y += signDY;
eY += 1.0 * -signDY;
}
}
};
Stage.prototype.plot = function (pt) {
if (pt.x < 0 || pt.y < 0 ||
pt.x > this.width || pt.y > this.height
) {
return;
}
this.context.fillStyle = this.color;
this.context.fillRect(
pt.x,
pt.y,
1,
1);
};
function setFrom(e) {
from = new Point(e.offsetX, e.offsetY);
}
function setTo(e) {
to = new Point(e.offsetX, e.offsetY);
st.clear();
st.drawLine(from, to);
}
var st, to, from,
c = document.createElement("canvas");
c.width = 640;
c.height = 480;
document.body.appendChild(c);
st = new Stage(c);
from = to = new Point(st.width / 2, st.height / 2);
document.querySelector("canvas")
.addEventListener("click", setFrom, false);
document.querySelector("canvas")
.addEventListener("mousemove", setTo, false);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment