import Point from './point.js'; function computeY(x, z) { return -x - z; } // convert real numbers to integers: // round off coords // throw out whichever one changed the most // re-establish "x + y + z = 0" function roundOff(hex) { let rX = Math.round(hex.x); let rY = Math.round(hex.y); let rZ = Math.round(hex.z); let xDiff = Math.abs(rX - hex.x); let yDiff = Math.abs(rY - hex.y); let zDiff = Math.abs(rZ - hex.z); if ((xDiff > yDiff) && (xDiff > zDiff)) { rX = -rY-rZ; } else if (yDiff > zDiff) { rY = -rX-rZ; } else { rZ = -rX-rY; } hex.x = rX === -0 ? 0 : rX; hex.y = rY === -0 ? 0 : rY; hex.z = rZ === -0 ? 0 : rZ; return hex; } export default class Hex extends Point { static qrToCube (q, r) { return { x: q, y: computeY(q, r), z: r, }; } static cubeToEvenR ({x, y, z}) { const col = x + (z + (z & 1)) / 2;; const row = z; return {col, row}; } static evenRToCube (col, row) { const x = col - (row + (row & 1)) / 2;; const z = row; const y = -x - z; return new Hex(x, y, z); } static cubeToEvenQ ({x, y, z}) { const col = x; const row = z + (x + (x & 1)) / 2; return {col, row}; } static evenQToCube (col, row) { const x = col; const z = row - (col + (col & 1)) / 2; const y = -x - z; return new Hex(x, y, z); } constructor() { super(); if (arguments.length === 1) { const {q, r, s = -q - r} = arguments[0]; const {x, z, y = -x - z} = arguments[0]; this.x = !isNaN(q) ? q : x; this.y = !isNaN(s) ? s : y; this.z = !isNaN(r) ? r : z; } else if (arguments.length === 2) { // hex = Hex(q, r); this.x = arguments[0]; this.z = arguments[1]; this.y = computeY(this.x, this.z); } else if (arguments.length === 3) { // hex = Hex(x, y, z); this.x = arguments[0]; this.y = arguments[1]; this.z = arguments[2]; } roundOff(this); } getX() {return this.x;} getY() {return this.y;} getZ() {return this.z;} setX (newX) {this.x = newX; return this;} setY (newY) {this.y = newY; return this;} setZ (newZ) {this.z = newZ; return this;} moveX (byX) {this.x += byX; return this;} moveY (byY) {this.y += byY; return this;} moveZ (byZ) {this.z += byZ; return this;} getQ () {return this.x;} getR () {return this.z;} setQ (newQ) { this.x = newQ; this.y = computeY(this.x, this.z); return this; } setR (newR) { this.z = newR; this.y = computeY(this.x, this.z); return this; } moveQ (byQ) { this.x += byQ; this.y = computeY(this.x, this.z); return this; } moveR (byR) { this.z += byR; this.y = computeY(this.x, this.z); return this; } getPoint () { return {x: this.x, y: this.y, z: this.z}; } setHex (newHex) { this.x = newHex.x; this.y = newHex.y; this.z = newHex.z; return this; } moveHex (byHex) { this.x += byHex.x; this.y += byHex.y; this.z += byHex.z; return this; } subtractHex (hex) { this.x -= hex.x; this.y -= hex.y; this.z -= hex.z; return this; } getAxial () {return {q: this.x, r: this.z};} setAxial (newAxial) { this.x = newAxial.q; this.z = newAxial.r; this.y = computeY(this.x, this.y); return this; } moveAxial (byAxial) { this.x += byAxial.q; this.z += byAxial.r; this.y = computeY(this.x, this.z); return this; } distance (hex) { return Math.max(Math.abs(this.x - hex.x), Math.abs(this.y - hex.y), Math.abs(this.z - hex.z)); } }