Skip to content

Instantly share code, notes, and snippets.

@grind086
Last active December 31, 2020 17:27
Show Gist options
  • Save grind086/d46aa2b8db025a60fcfd0e2d46701c2d to your computer and use it in GitHub Desktop.
Save grind086/d46aa2b8db025a60fcfd0e2d46701c2d to your computer and use it in GitHub Desktop.
Typescript implementation of the Bresenham Line-Drawing Algorithm using generators
/* Iterate integer points on a line where dx >= dy and x0 <= x1. */
function *iter_line_low(
[x0, y0]: [number, number],
[x1, y1]: [number, number]
): Generator<[number, number], void, unknown> {
const dx = x1 - x0;
const dy = y1 - y0;
let y = y0;
let e = 0;
if (dy === 0) {
for (let x = x0; x <= x1; x++) {
yield [x, y];
}
}
else if (dy > 0) {
for (let x = x0; x <= x1; x++) {
yield [x, y];
e += dy;
if ((e << 1) >= dx) {
y += 1;
e -= dx;
}
}
}
else {
for (let x = x0; x <= x1; x++) {
yield [x, y];
e += dy;
if ((e << 1) <= -dx) {
y -= 1;
e += dx;
}
}
}
}
/* Iterate integer points on a line where dy >= dx and y0 <= y1. */
function *iter_line_high(
[x0, y0]: [number, number],
[x1, y1]: [number, number]
): Generator<[number, number], void, unknown> {
const dx = x1 - x0;
const dy = y1 - y0;
let x = x0;
let e = 0;
if (dx === 0) {
for (let y = y0; y <= y1; y++) {
yield [x, y];
}
}
else if (dx > 0) {
for (let y = y0; y <= y1; y++) {
yield [x, y];
e += dx;
if ((e << 1) >= dy) {
x += 1;
e -= dy;
}
}
}
else {
for (let y = y0; y <= y1; y++) {
yield [x, y];
e += dx;
if ((e << 1) <= -dy) {
x -= 1;
e += dy;
}
}
}
}
/* Iterate integer points on a line. Input points *must* be comprised of integers. */
function iter_line(
p0: [number, number],
p1: [number, number]
): Generator<[number, number], void, unknown> {
if (Math.abs(p0[0] - p1[0]) >= Math.abs(p0[1] - p1[1])) {
return p0[0] <= p1[0]
? iter_line_low(p0, p1)
: iter_line_low(p1, p0);
} else {
return p0[1] <= p1[1]
? iter_line_high(p0, p1)
: iter_line_high(p1, p0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment