Skip to content

Commit

Permalink
fix(grid-iterators): enforce int coords
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Mar 3, 2021
1 parent daded51 commit e8e570f
Show file tree
Hide file tree
Showing 18 changed files with 57 additions and 16 deletions.
3 changes: 2 additions & 1 deletion packages/grid-iterators/src/circle.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { hline } from "./hvline";
import { asInt } from "./utils";

export function* circle(cx: number, cy: number, r: number, fill = true) {
[cx, cy, r] = asInt(cx, cy, r);
if (r < 1) return;
r |= 0;
let x = 0;
let y = r;
let y2 = r * r;
Expand Down
3 changes: 3 additions & 0 deletions packages/grid-iterators/src/column-ends.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { asInt } from "./utils";

/**
* Filtered version of {@link columns2d}, only including end points of
* each column.
Expand All @@ -6,6 +8,7 @@
* @param rows -
*/
export function* columnEnds2d(cols: number, rows = cols) {
[cols, rows] = asInt(cols, rows);
rows--;
for (let x = 0; x < cols; x++) {
yield [x, 0];
Expand Down
4 changes: 2 additions & 2 deletions packages/grid-iterators/src/columns.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { map, range2d } from "@thi.ng/transducers";
import { swapxy } from "./swap";
import { swapxy } from "./utils";

/**
* Yields sequence of 2D grid coordinates in column-major order.
Expand All @@ -8,4 +8,4 @@ import { swapxy } from "./swap";
* @param rows
*/
export const columns2d = (cols: number, rows = cols) =>
map(swapxy, range2d(rows, cols));
map(swapxy, range2d(rows | 0, cols | 0));
2 changes: 2 additions & 0 deletions packages/grid-iterators/src/diagonal-ends.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { diagonal2d } from "./diagonal";
import { asInt } from "./utils";

/**
* Filtered version of {@link diagonal2d}, only including end points of
Expand All @@ -12,6 +13,7 @@ import { diagonal2d } from "./diagonal";
* @param rows -
*/
export function* diagonalEnds2d(cols: number, rows = cols) {
[cols, rows] = asInt(cols, rows);
const num = cols * rows - 1;
const maxX = cols - 1;
const maxY = rows - 1;
Expand Down
3 changes: 3 additions & 0 deletions packages/grid-iterators/src/diagonal.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { asInt } from "./utils";

/**
* Yields sequence of 2D grid coordinates in diagonal order starting at
* [0,0] and using given `cols` and `rows`. Each diagonal starts at y=0
Expand All @@ -10,6 +12,7 @@
* @param rows -
*/
export function* diagonal2d(cols: number, rows = cols) {
[cols, rows] = asInt(cols, rows);
const num = cols * rows - 1;
for (let x = 0, y = 0, nx = 1, ny = 0, i = 0; i <= num; i++) {
yield [x, y];
Expand Down
3 changes: 3 additions & 0 deletions packages/grid-iterators/src/hilbert.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { asInt } from "./utils";

/**
* Yields sequence of 2D grid coordinates along 2D Hilbert curve using
* given `cols` and `rows` (each max. 32768 (2^15)).
Expand All @@ -9,6 +11,7 @@
* @param rows -
*/
export function* hilbert2d(cols: number, rows = cols) {
[cols, rows] = asInt(cols, rows);
let hIndex = 0; // hilbert curve index
let hOrder = 0; // hilbert curve order
// fit to number of buckets
Expand Down
4 changes: 4 additions & 0 deletions packages/grid-iterators/src/hvline.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { asInt } from "./utils";

export function* hline(x: number, y: number, len: number) {
[x, y, len] = asInt(x, y, len);
for (const xmax = x + len; x < xmax; x++) {
yield [x, y];
}
}

export function* vline(x: number, y: number, len: number) {
[x, y, len] = asInt(x, y, len);
for (const ymax = y + len; y < ymax; y++) {
yield [x, y];
}
Expand Down
6 changes: 3 additions & 3 deletions packages/grid-iterators/src/interleave.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { map, range2d } from "@thi.ng/transducers";
import { swapxy } from "./swap";
import { swapxy } from "./utils";

/**
* Yields 2D grid coordinates in the order of interleaved columns with
Expand All @@ -18,7 +18,7 @@ import { swapxy } from "./swap";
*/
export function* interleaveColumns2d(cols: number, rows = cols, step = 2) {
for (let j = 0; j < step; j++) {
yield* map(swapxy, range2d(0, rows, j, cols, 1, step));
yield* map(swapxy, range2d(0, rows | 0, j, cols | 0, 1, step | 0));
}
}

Expand All @@ -39,6 +39,6 @@ export function* interleaveColumns2d(cols: number, rows = cols, step = 2) {
*/
export function* interleaveRows2d(cols: number, rows = cols, step = 2) {
for (let j = 0; j < step; j++) {
yield* range2d(0, cols, j, rows, 1, step);
yield* range2d(0, cols | 0, j, rows | 0, 1, step | 0);
}
}
20 changes: 11 additions & 9 deletions packages/grid-iterators/src/line.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
export function* line(ox: number, oy: number, ex: number, ey: number) {
const dx = Math.abs(ex - ox);
const dy = -Math.abs(ey - oy);
import { asInt } from "./utils";

let sx = ox < ex ? 1 : -1;
let sy = oy < ey ? 1 : -1;
export function* line(ax: number, ay: number, bx: number, by: number) {
[ax, ay, bx, by] = asInt(ax, ay, bx, by);
const dx = Math.abs(bx - ax);
const dy = -Math.abs(by - ay);
const sx = ax < bx ? 1 : -1;
const sy = ay < by ? 1 : -1;
let err = dx + dy;

while (true) {
yield [ox, oy];
if (ox === ex && oy === ey) return;
yield [ax, ay];
if (ax === bx && ay === by) return;
let t = err << 1;
if (t < dx) {
err += dx;
oy += sy;
ay += sy;
}
if (t > dy) {
err += dy;
ox += sx;
ax += sx;
}
}
}
2 changes: 2 additions & 0 deletions packages/grid-iterators/src/random.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { shuffle } from "@thi.ng/arrays";
import { IRandom, SYSTEM } from "@thi.ng/random";
import { range } from "@thi.ng/transducers";
import { asInt } from "./utils";

/**
* Yields 2D grid coordinates in random order w/ support for optional
Expand All @@ -12,6 +13,7 @@ import { range } from "@thi.ng/transducers";
* @param rnd - PRNG
*/
export function* random2d(cols: number, rows = cols, rnd: IRandom = SYSTEM) {
[cols, rows] = asInt(cols, rows);
for (let i of shuffle([...range(cols * rows)], undefined, rnd)) {
yield [i % cols, (i / cols) | 0];
}
Expand Down
3 changes: 3 additions & 0 deletions packages/grid-iterators/src/row-ends.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { asInt } from "./utils";

/**
* Filtered version of {@link rows2d}, only including end points of
* each row.
Expand All @@ -6,6 +8,7 @@
* @param rows -
*/
export function* rowEnds2d(cols: number, rows = cols) {
[cols, rows] = asInt(cols, rows);
cols--;
for (let y = 0; y < rows; y++) {
yield [0, y];
Expand Down
3 changes: 2 additions & 1 deletion packages/grid-iterators/src/rows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ import { range2d } from "@thi.ng/transducers";
* @param cols
* @param rows
*/
export const rows2d = (cols: number, rows = cols) => range2d(cols, rows);
export const rows2d = (cols: number, rows = cols) =>
range2d(cols | 0, rows | 0);
3 changes: 3 additions & 0 deletions packages/grid-iterators/src/spiral.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { asInt } from "./utils";

/**
* Yields sequence of 2D grid coordinates in outward spiral order
* starting from the center, given `cols` and `rows`.
Expand All @@ -9,6 +11,7 @@
* @param rows -
*/
export function* spiral2d(cols: number, rows = cols) {
[cols, rows] = asInt(cols, rows);
const num = cols * rows;
const center = (Math.min(cols, rows) - 1) >> 1;
for (let i = 0; i < num; i++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ export const swapxy = (p: number[]) => {
p[1] = t;
return p;
};

/** @internal */
export const asInt = (...args: number[]) => args.map((x) => x | 0);
2 changes: 2 additions & 0 deletions packages/grid-iterators/src/zcurve.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ceilPow2 } from "@thi.ng/binary";
import { demux2 } from "@thi.ng/morton";
import { asInt } from "./utils";

/**
* Yields 2D grid coordinates in Z-curve (Morton) order. A perfect
Expand All @@ -11,6 +12,7 @@ import { demux2 } from "@thi.ng/morton";
* @param rows -
*/
export function* zcurve2d(cols: number, rows = cols) {
[cols, rows] = asInt(cols, rows);
const max = ceilPow2(Math.pow(Math.max(cols, rows), 2));
for (let i = 0; i < max; i++) {
const p = demux2(i);
Expand Down
3 changes: 3 additions & 0 deletions packages/grid-iterators/src/zigzag-columns.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { asInt } from "./utils";

/**
* Yields sequence of 2D grid coordinates in zigzag column order
* starting from [0,0], given `cols` and `rows`.
Expand All @@ -10,6 +12,7 @@
*
*/
export function* zigzagColumns2d(cols: number, rows = cols) {
[cols, rows] = asInt(cols, rows);
const num = cols * rows;
for (let i = 0; i < num; i++) {
const x = (i / rows) | 0;
Expand Down
3 changes: 3 additions & 0 deletions packages/grid-iterators/src/zigzag-diagonal.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { asInt } from "./utils";

/**
* Similar to {@link diagonal2d}, but yields 2D grid coordinates in zigzag
* diagonal order starting at [0,0] and using given `cols` and `rows`.
Expand All @@ -6,6 +8,7 @@
* @param rows -
*/
export function* zigzagDiagonal2d(cols: number, rows = cols) {
[cols, rows] = asInt(cols, rows);
const num = cols * rows - 1;
for (
let x = 0, y = 0, ny = 0, dx = -1, dy = 1, d = 0, down = true, i = 0;
Expand Down
3 changes: 3 additions & 0 deletions packages/grid-iterators/src/zigzag-rows.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { asInt } from "./utils";

/**
* Yields sequence of 2D grid coordinates in zigzag row order starting
* from [0,0], given `cols` and `rows`.
Expand All @@ -10,6 +12,7 @@
*
*/
export function* zigzagRows2d(cols: number, rows = cols) {
[cols, rows] = asInt(cols, rows);
const num = cols * rows;
for (let i = 0; i < num; i++) {
let x = i % cols;
Expand Down

0 comments on commit e8e570f

Please sign in to comment.