Files
Tessellate/src/hex.js
2019-01-06 15:34:56 -05:00

183 lines
3.3 KiB
JavaScript

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));
}
}