Finite boards (#1)
This commit is contained in:
105
src/cartographerPointyXY.js
Normal file
105
src/cartographerPointyXY.js
Normal file
@@ -0,0 +1,105 @@
|
||||
import Cartographer from './cartographer.js';
|
||||
|
||||
import {rangeInclusive, sqrt2} from './utils.js';
|
||||
|
||||
import Square from './square.js';
|
||||
import Point from './point.js';
|
||||
|
||||
export default class CartographerPointyXY extends Cartographer {
|
||||
constructor(settings) {
|
||||
super(settings);
|
||||
|
||||
[
|
||||
'maxWidth',
|
||||
'minWidth',
|
||||
|
||||
'horizontalDistance',
|
||||
'verticalDistance',
|
||||
|
||||
'calculateHorizontalScale',
|
||||
'calculateVerticalScale',
|
||||
|
||||
'tileToPixel',
|
||||
'pixelToTile',
|
||||
'boundingBox',
|
||||
].map(method => this[method] = this[method].bind(this));
|
||||
}
|
||||
|
||||
maxWidth() {
|
||||
return this.minWidth() * sqrt2;
|
||||
}
|
||||
|
||||
minWidth() {
|
||||
return this.scale * 2;
|
||||
}
|
||||
|
||||
horizontalDistance() {
|
||||
return this.maxWidth() / 2;
|
||||
}
|
||||
|
||||
verticalDistance() {
|
||||
return this.maxWidth() / 2;
|
||||
}
|
||||
|
||||
calculateHorizontalScale(pixels, tiles) {
|
||||
return pixels / sqrt2 / tiles;
|
||||
}
|
||||
|
||||
calculateVerticalScale(pixels, tiles) {
|
||||
return pixels / sqrt2 / tiles;
|
||||
}
|
||||
|
||||
tileToPixel(square) {
|
||||
const x = square.getX();
|
||||
const y = square.getY();
|
||||
|
||||
// (above/below axis) * (distance from axis) / (size)
|
||||
let pixelX = (x < y ? -1 : 1) * (Math.abs(y - x) / sqrt2) * this.minWidth();
|
||||
let pixelY = (-x < y ? 1 : -1) * (Math.abs(x + y) / sqrt2) * this.minWidth();
|
||||
|
||||
return new Point(pixelX + this.originX, this.originY - pixelY);
|
||||
}
|
||||
|
||||
pixelToTile(point) {
|
||||
const pixelX = point.getX() - this.originX;
|
||||
const pixelY = this.originY - point.getY();
|
||||
|
||||
// (above/below axis) * (distance from axis) / (size)
|
||||
const x = (-pixelX < pixelY ? 1 : -1) * (Math.abs(pixelX + pixelY) / sqrt2) / this.minWidth();
|
||||
const y = (pixelX < pixelY ? 1 : -1) * (Math.abs(pixelY - pixelX) / sqrt2) / this.minWidth();
|
||||
|
||||
return new Square(x, y);
|
||||
}
|
||||
|
||||
boundingBox(upperLeftPoint, upperRightPoint, lowerLeftPoint, lowerRightPoint) {
|
||||
const upperLeftTile = this.pixelToTile(upperLeftPoint);
|
||||
const lowerRightTile = this.pixelToTile(lowerRightPoint);
|
||||
const upperRightTile = this.pixelToTile(upperRightPoint);
|
||||
const lowerLeftTile = this.pixelToTile(lowerLeftPoint);
|
||||
|
||||
const columns = rangeInclusive(lowerLeftTile.getX(), upperRightTile.getX());
|
||||
|
||||
const upperLeftIntercept = upperLeftTile.getY() - upperLeftTile.getX();
|
||||
const upperRightIntercept = upperLeftTile.getY() + upperLeftTile.getX();
|
||||
|
||||
const lowerLeftIntercept = lowerRightTile.getY() - lowerRightTile.getX();
|
||||
const lowerRightIntercept = lowerRightTile.getY() + lowerRightTile.getX();
|
||||
|
||||
const aboutHalf = Math.floor(columns.length / 2);
|
||||
const midway = columns.length % 2 ? columns[aboutHalf] :
|
||||
(columns[aboutHalf - 1] + columns[aboutHalf]) / 2;
|
||||
|
||||
return columns.map(x => {
|
||||
let top = x < midway ? upperLeftIntercept + x : upperRightIntercept - x;
|
||||
let bottom = x < midway ? lowerRightIntercept - x : lowerLeftIntercept + x;
|
||||
|
||||
bottom = Math.min(bottom, top);
|
||||
top = Math.max(bottom, top);
|
||||
|
||||
// push out by 1 on either end to account for interlocking tiles
|
||||
const rows = rangeInclusive(bottom - 1, top + 1);
|
||||
|
||||
return rows.map(y => new Square(x, y));
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user