hexagrid
Version:
Hexagonal grid with fast lookup
134 lines • 4.39 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("./utils");
class Hex {
constructor(q = 0, r = 0, data) {
this.q = q;
this.r = r;
this.data = data;
}
get s() {
return 0 - this.q - this.r;
}
rotateRight(times = 1, _center) {
// Deal with negative and positive numbers
times = (times % 6 + 6) % 6;
const center = _center ? { q: _center.q, r: _center.r } : { q: 0, r: 0 };
if (center) {
[this.q, this.r] = [this.q - center.q, this.r - center.r];
}
switch (times) {
case 0: break;
case 1:
[this.q, this.r] = [-this.r, -this.s];
break;
case 2:
[this.q, this.r] = [this.s, this.q];
break;
case 3:
[this.q, this.r] = [-this.q, -this.r];
break;
case 4:
[this.q, this.r] = [this.r, this.s];
break;
case 5:
[this.q, this.r] = [-this.s, -this.q];
break;
default: throw new TypeError("Hex.rotateLeft should have an integer as parameter");
}
if (center) {
[this.q, this.r] = [this.q + center.q, this.r + center.r];
}
}
rotateLeft(times = 1, center) {
this.rotateRight(-times, center);
}
toString() {
return `${this.q}x${this.r}`;
}
toJSON() {
return {
q: this.q,
r: this.r,
s: this.s,
data: this.data
};
}
/**
* Creates an hexagon of radius r around options.center, feeding the data supplied.
*
* A radius of 0 gives a single hexagon
* @param radius
* @param options
*/
static hexagon(radius, options) {
const { center, data } = utils_1.loadDefaults(options, { data: [], center: { q: 0, r: 0, s: 0 } });
const ret = [];
let totalLength = 0;
for (let r = radius; r >= 0; r--) {
ret.push(this.ring(r, { center, data: data.slice(totalLength) }));
totalLength += ret[ret.length - 1].length;
}
return [].concat(...ret);
}
/**
* Creates a ring of radius r around options.center, feeding the data supplied
*
* @param radius
* @param options
*/
static ring(radius, options) {
const { center, data } = utils_1.loadDefaults(options, { data: [], center: { q: 0, r: 0, s: 0 } });
const ret = [];
const feed = () => ret.length < data.length ? data[ret.length] : undefined;
// flat N to NE
for (let [q, r] = [radius, 0]; q >= 0; q--, r++) {
ret.push(new this(q, r, feed()));
}
// NE to SE
for (let [q, r] = [-1, radius]; q >= -radius; q--) {
ret.push(new this(q, r, feed()));
}
// SE to S
for (let [q, r] = [-radius, radius - 1]; r >= 0; r--) {
ret.push(new this(q, r, feed()));
}
// S to SW
for (let [q, r] = [-radius + 1, -1]; r >= -radius; r--, q++) {
ret.push(new this(q, r, feed()));
}
// SW to NW
for (let [q, r] = [1, -radius]; q <= radius; q++) {
ret.push(new this(q, r, feed()));
}
// NW to N
for (let [q, r] = [radius, -radius + 1]; r < 0; r++) {
ret.push(new this(q, r, feed()));
}
for (let hex of ret) {
hex.q += center.q;
hex.r += center.r;
}
return ret;
}
/**
* Creates a child class that extends Hex, and initializes by default
* with data = `defaultData`
*
* @param defaultData
*/
static extend(defaultData) {
return class ExtendedHex extends this {
constructor(q, r, data) {
if (typeof defaultData === "object") {
super(q, r, Object.assign({}, defaultData, data));
}
else {
super(q, r, data === undefined ? defaultData : data);
}
}
};
}
}
exports.default = Hex;
//# sourceMappingURL=hex.js.map