Last active
December 31, 2020 17:27
-
-
Save grind086/d46aa2b8db025a60fcfd0e2d46701c2d to your computer and use it in GitHub Desktop.
Typescript implementation of the Bresenham Line-Drawing Algorithm using generators
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
/* 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