Skip to content

Instantly share code, notes, and snippets.

@mrtnbroder
Forked from masaeedu/spiral.js
Created March 29, 2019 10:07
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 mrtnbroder/1632a05f9a8c0e4f66dc0b84c004ed5d to your computer and use it in GitHub Desktop.
Save mrtnbroder/1632a05f9a8c0e4f66dc0b84c004ed5d to your computer and use it in GitHub Desktop.
// Utils
const range = n => [...Array(n).keys()];
const add = ([x0, y0]) => ([x1, y1]) => [x0 + x1, y0 + y1];
const rotate = θ => ([x, y]) => [
Math.round(x * Math.cos(θ) - y * Math.sin(θ)),
Math.round(x * Math.sin(θ) + y * Math.cos(θ))
];
const map = f => g =>
function*() {
for (const v of g()) {
yield f(v);
}
};
// Implementation
const spiralOut = i => {
const n = Math.floor(i / 2) + 1;
const leg = range(n).map(x => [x, 0]);
const transform = p => add([n, 0])(rotate(-Math.PI / 2)(p));
return function*() {
yield* leg;
yield* map(transform)(spiralOut(i + 1))();
};
};
const spiralIn = ([w, h]) => {
const leg = range(w).map(x => [x, 0]);
const transform = p => add([w - 1, 1])(rotate(Math.PI / 2)(p));
return w * h === 0
? function*() {}
: function*() {
yield* leg;
yield* map(transform)(spiralIn([h - 1, w]))();
};
};
let i = 0;
for (let p of spiralOut(0)()) {
if (i++ > 30) break;
console.log(p);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment