import { Dimension, Coordinate, Coordinate2D, Coordinate3D } from './coordinate.js';
/**
* Represents a coordinate matrix.
* @abstract
* @classdesc Abstract Coordinate Matrix for representation purposes
*/
export class CoordinateMatrix {
constructor() {
if (new.target === CoordinateMatrix)
throw new TypeError('Cannot instantiate abstract class')
}
/**
* Gets the iterator for this CoordinateMatrix.
* @returns {Iterator<Coordinate>} The iterator for this CoordinateMatrix.
*/
[Symbol.iterator]() {
return this.coordinates.values()
}
/**
* Returns the dimension of this CoordinateMatrix.
* @returns {Dimension} The dimension of this CoordinateMatrix.
*/
get dimension() {
throw new Error('Abstract method')
}
/**
* Returns the coordinates of this CoordinateMatrix.
* @returns {Array<Coordinate>} The coordinates of this CoordinateMatrix.
*/
get coordinates() {
throw new Error('Abstract method')
}
}
export class CoordinateMatrix2D extends CoordinateMatrix {
/**
* The minimum x value of this matrix.
* @type {number}
*/
minX;
/**
* The maximum x value of this matrix.
* @type {number}
*/
maxX;
/**
* The minimum y value of this matrix.
* @type {number}
*/
minY;
/**
* The maximum y value of this matrix.
* @type {number}
*/
maxY;
/**
* The starting coordinate of this matrix.
* @type {Coordinate2D}
*/
start;
/**
* Constructs a CoordinateMatrix2D.
* @constructor
* @param {number} minX The minimum x value.
* @param {number} maxX The maximum x value.
* @param {number} minY The minimum y value.
* @param {number} maxY The maximum y value.
* @param {Coordinate2D} start The starting coordinate.
* @example
* new CoordinateMatrix2D(0, 1, 0, 1, new Coordinate2D(0, 0))
*/
constructor(minX, maxX, minY, maxY, start) {
super();
if (minX > maxX) throw new SyntaxError(`minX cannot be greater than maxX: ${minX} > ${maxX}`);
if (minY > maxY) throw new SyntaxError(`minY cannot be greater than maxY: ${minY} > ${maxY}`);
this.minX = minX;
this.maxX = maxX;
this.minY = minY;
this.maxY = maxY;
this.start = start;
}
get dimension() {
return Dimension.TWO;
}
get coordinates() {
const coords = [];
for (let x = this.minX; x <= this.maxX; x++) {
for (let y = this.minY; y <= this.maxY; y++) {
coords.push(new Coordinate2D(x, y));
}
}
return coords;
}
/**
* Gets the string representation of this CoordinateMatrix2D.
* @returns {string} The string representation of this CoordinateMatrix2D.
*/
toString() {
return `(${this.minX}, ${this.maxX}, ${this.minY}, ${this.maxY})^${this.start.toString()}`;
}
// Statics
/**
* Converts a string to a CoordinateMatrix2D.
* @static
* @param {string} str The string to convert.
* @returns {CoordinateMatrix2D} The parsed CoordinateMatrix2D.
* @throws {SyntaxError} If the string is invalid.
* @example
* CoordinateMatrix2D.fromString('(0, 1, 0, 1)^[0, 0]')
*/
static fromString(str) {
const split = str.split(/\^/)
if (split.length !== 2) throw new SyntaxError(`Invalid 3D matrix string: ${str}`)
const coords = split[1].replace(/[\[\]\s]/g, "").split(/,/)
const matrix = split[0].replace(/[()\s]/g, "").split(/,/)
if (coords.length !== 2) throw new SyntaxError(`Invalid 2D point: ${str}`)
if (matrix.length !== 4) throw new SyntaxError(`Invalid 2D matrix: ${str}`)
const cx = parseFloat(coords[0]), cy = parseFloat(coords[1])
const x1 = parseInt(matrix[0]), x2 = parseInt(matrix[1])
const y1 = parseInt(matrix[2]), y2 = parseInt(matrix[3])
if (x1 > x2) throw new SyntaxError(`minX cannot be greater than maxX: ${str}`)
if (y1 > y2) throw new SyntaxError(`minY cannot be greater than maxY: ${str}`)
return new CoordinateMatrix2D(x1, x2, y1, y2, new Coordinate2D(cx, cy))
}
}
/**
* Represents a 3D coordinate matrix.
*/
export class CoordinateMatrix3D extends CoordinateMatrix {
/**
* The minimum x value of this matrix.
* @type {number}
*/
minX;
/**
* The maximum x value of this matrix.
* @type {number}
*/
maxX;
/**
* The minimum y value of this matrix.
* @type {number}
*/
minY;
/**
* The maximum y value of this matrix.
* @type {number}
*/
maxY;
/**
* The minimum z value of this matrix.
* @type {number}
*/
minZ;
/**
* The maximum z value of this matrix.
* @type {number}
*/
maxZ;
/**
* The starting coordinate of this matrix.
* @type {Coordinate3D}
*/
start;
/**
* Constructs a CoordinateMatrix3D.
* @constructor
* @param {number} minX The minimum x value.
* @param {number} maxX The maximum x value.
* @param {number} minY The minimum y value.
* @param {number} maxY The maximum y value.
* @param {number} minZ The minimum z value.
* @param {number} maxZ The maximum z value.
* @param {Coordinate3D} start The starting coordinate.
* @example
* new CoordinateMatrix3D(0, 1, 0, 1, 0, 1, new Coordinate3D(0, 0, 0))
*/
constructor(minX, maxX, minY, maxY, minZ, maxZ, start) {
super();
this.minX = minX;
this.maxX = maxX;
this.minY = minY;
this.maxY = maxY;
this.minZ = minZ;
this.maxZ = maxZ;
this.start = start;
}
get dimension() {
return Dimension.THREE;
}
get coordinates() {
const coords = [];
for (let x = this.minX; x <= this.maxX; x++) {
for (let y = this.minY; y <= this.maxY; y++) {
for (let z = this.minZ; z <= this.maxZ; z++) {
coords.push(new Coordinate3D(x, y, z));
}
}
}
return coords;
}
/**
* Gets the string representation of this CoordinateMatrix3D.
* @returns {string} The string representation of this CoordinateMatrix3D.
*/
toString() {
return `(${this.minX}, ${this.maxX}, ${this.minY}, ${this.maxY}, ${this.minZ}, ${this.maxZ})^${this.start.toString()}`;
}
// Statics
/**
* Converts a string to a CoordinateMatrix3D.
* @static
* @param {string} str The string to convert.
* @returns {CoordinateMatrix3D} The parsed CoordinateMatrix3D.
* @throws {SyntaxError} If the string is invalid.
* @example
* CoordinateMatrix3D.fromString('(0, 1, 0, 1, 0, 1)^[0, 0, 0]')
*/
static fromString(str) {
const split = str.split(/\^/)
if (split.length !== 2) throw new SyntaxError(`Invalid 3D matrix string: ${str}`)
const coords = split[1].replace(/[\[\]\s]/g, "").split(/,/)
const matrix = split[0].replace(/[()\s]/g, "").split(/,/)
if (coords.length !== 3) throw new SyntaxError(`Invalid 2D point: ${str}`)
if (matrix.length !== 6) throw new SyntaxError(`Invalid 2D matrix: ${str}`)
const cx = parseFloat(coords[0]), cy = parseFloat(coords[1]), cz = parseFloat(coords[2])
const x1 = parseInt(matrix[0]), x2 = parseInt(matrix[1])
const y1 = parseInt(matrix[2]), y2 = parseInt(matrix[3])
const z1 = parseInt(matrix[4]), z2 = parseInt(matrix[5])
if (x1 > x2) throw new SyntaxError(`minX cannot be greater than maxX: ${str}`)
if (y1 > y2) throw new SyntaxError(`minY cannot be greater than maxY: ${str}`)
if (z1 > z2) throw new SyntaxError(`minZ cannot be greater than maxZ: ${str}`)
return new CoordinateMatrix3D(x1, x2, y1, y2, z1, z2, new Coordinate3D(cx, cy, cz))
}
}