183 lines
3.3 KiB
JavaScript
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));
|
|
}
|
|
}
|