UNPKG

plotboilerplate

Version:

A simple javascript plotting boilerplate for 2d stuff.

284 lines (283 loc) 9.27 kB
/** * @author Ikaros Kappler * @date 2013-11-27 * @modified 2014-04-05 Ikaros Kappler (member array outerTilePolygons added). * @modified 2015-03-19 Ikaros Kappler (added toSVG()). * @modified 2020-10-30 Refactored the this super class to work with PlotBoilerplate. * @modified 2020-11-11 Ported the class from vanilla JS to TypeScript. * @version 2.0.1-alpha * @name GirihTile **/ import { Bounds } from "../../Bounds"; import { Polygon } from "../../Polygon"; import { Vertex } from "../../Vertex"; import { XYCoords } from "../../interfaces"; export declare enum TileType { UNKNOWN = "UNKNOWN", DECAGON = "DECAGON", PENTAGON = "PENTAGON", IRREGULAR_HEXAGON = "IRREGULAR_HEXAGON", RHOMBUS = "RHOMBUS", BOW_TIE = "BOW_TIE", PENROSE_RHOMBUS = "PENROSE_RHOMBUS" } export interface IAdjacency { edgeIndex: number; offset: XYCoords; } /** * @classdesc This is a general tile superclass. All other tile classes extends this one. * * Rule: * * the outer and the inner sub polygons must be inside the main polygon's bounds. * * @requires Bounds * @requires Polyon * @requires Vertex * @requires XYCoords */ export declare abstract class GirihTile extends Polygon { /** * The center of this tile. * * @name position * @member {Vertex} * @memberof GirihTile * @type {Vertex} * @instance */ position: Vertex; /** * The edge length of this tile (all edges of a Girih tile have same length). * * @name edgeLength * @member {number} * @memberof GirihTile * @type {number} * @readonly * @instance */ readonly edgeLength: number; /** * The rotation of this tile. This is stored to make cloning easier. * * @name rotation. * @member {number} * @memberof GirihTile * @type {number} * @instance */ rotation: number; /** * The symmetry (=order) of this tile. This is the number of steps used for a full * rotation (in this Girih case: 10). Future Girih implementations might have other symmetries. * * @name symmetry * @member {number} * @memberof GirihTile * @type {number} * @instance */ symmetry: number; /** * The unique symmetries. This must be an nth part of the global `symmetry`. * Rotating this tile `uniqueSymmetries' times results in the same visual tile (flipped around * a symmetry axis). * * @name uniqueSymmetries * @member {number} * @memberof GirihTile * @type {number} * @instance */ uniqueSymmetries: number; /** * The inner tile polygons. * * @name innerTilePolygons * @member {Array<Polygon>} * @memberof GirihTile * @type {Array<Polygon>} * @instance */ innerTilePolygons: Array<Polygon>; /** * The outer tile polygons. * * @name outerTilePolygons * @member {Array<Polygon>} * @memberof GirihTile * @type {Array<Polygon>} * @instance */ outerTilePolygons: Array<Polygon>; /** * An identifier for the tile type. * * @name tileType * @member {TileType} * @memberof GirihTile * @type {TileType} * @instance */ tileType: TileType; /** * The initial bounds (of the un-rotated tile). These are required to calculate the * correct texture mapping. * * @name baseBounds * @member {Bounds} * @memberof GirihTile * @type {Bounds} * @instance */ baseBounds: Bounds; /** * A rectangle on the shipped texture image (`girihtexture-500px.png`) marking the * texture position. The bounds are relative, so each component must be in [0..1]. * The texture is a square. * * @name textureSource * @member {Bounds} * @memberof GirihTile * @type {Bounds} * @instance */ readonly textureSource: Bounds; /** * An epsilon to use for detecting adjacent edges. 0.001 seems to be a good value. * Adjust if needed. * * @name epsilon * @member {number} * @memberof GirihTile * @type {number} * @static */ static epsilon: number; /** * The default edge length. * * @name DEFAULT_EDGE_LENGTH * @member {number} * @memberof GirihTile * @type {number} * @readonly * @static */ static readonly DEFAULT_EDGE_LENGTH: number; /** * @constructor * @memberof GirihTile * @abstract class * @param {Vertex} position - The position of the tile. * @param {number} edgeLength - The edge length (default is GirihTile.DEFAULT_EDGE_LENGTH). * @param {TileType} tileType - One of `TileType.*` enum members. **/ constructor(position: Vertex, edgeLength?: number, tileType?: TileType); /** * @abstract Subclasses must override this. */ abstract clone(): GirihTile; /** * Move this tile around (together will all inner polygons). * As this function overrides Polygon.move(...), the returned * instance (this) must be of type `Polygon`. * * @name move * @instance * @override * @memberof GirihTile * @param {XYCoords} amount * @return {Polygon} this */ move(amount: XYCoords): Polygon; /** * Find the adjacent tile (given by the template tile) * Note that the tile itself will be modified (rotated and moved to the correct position). * * @name findAdjacentTilePosition * @memberof GirihTile * @instance * @param {number} edgeIndex - The edge number of the you you want to find adjacency for. * @param {Polygon} tile - The polygon (or tile) you want to find adjacency for at the specified edge. * @return {IAdjacency|null} Adjacency information or null if the passed tile does not match. */ findAdjacentTilePosition(edgeIndex: number, tile: Polygon): IAdjacency | null; /** * Find all possible adjacent tile positions (and rotations) for `neighbourTile`. * * @name transformTileToAdjacencies * @memberof GirihTile * @instance * @param {number} baseEdgeIndex - The edge number of the you you want to find adjacencies for. * @param {GirihTile} neighbourTile - The polygon (or tile) you want to find adjacencies for at the specified edge. * @return {IAdjacency|null} Adjacency information or null if the passed tile does not match. */ transformTileToAdjacencies(baseEdgeIndex: number, neighbourTile: GirihTile): Array<GirihTile>; /** * Apply adjacent tile position to `neighbourTile`. * * @name transformTilePositionToAdjacencies * @memberof GirihTile * @instance * @param {number} baseEdgeIndex - The edge number of the you you want to apply adjacent position for. * @param {Polygon} neighbourTile - The polygon (or tile) you want to find adjacency for at the specified edge. * @return {Polygon|null} the passed tile itself if adjacency was found, null otherwise. */ transformTilePositionToAdjacency<P extends Polygon>(baseEdgeIndex: number, neighbourTile: P): P | null; /** * Get the inner tile polygon at the given index. * This function applies MOD to the index. * * @name getInnerTilePolygonAt * @instance * @memberof GirihTile * @param {number} index * @return {Polygon} The sub polygon (inner tile) at the given index. **/ getInnerTilePolygonAt(index: number): Polygon; /** * Get the outer tile polygon at the given index. * This function applies MOD to the index. * * @name getOuterTilePolygonAt * @instance * @memberof GirihTile * @param {number} index * @return {Polygon} The sub polygon (outer tile) at the given index. **/ getOuterTilePolygonAt(index: number): Polygon; /** * Rotate this tile * Note: this function behaves a bitdifferent than the genuine Polygon.rotate function! * Polygon has the default center of rotation at (0,0). * The GirihTile rotates around its center (position) by default. * * @name rotate * @instance * @memberof GirihTile * @param {number} angle - The angle to use for rotation. * @param {Vertex?} center - The center of rotation (default is this.position). * @return {Polygon} this **/ rotate(angle: number, center?: Vertex): GirihTile; /** * This function locates the closest tile edge (polygon edge) * to the passed point. * * Currently the edge distance to a point is measured by the * euclidian distance from the edge's middle point. * * Idea: move this function to Polygon? * * @name locateEdgeAtPoint * @instance * @memberof GirihTile * @param {XYCoords} point - The point to detect the closest edge for. * @param {number} tolerance - The tolerance (=max distance) the detected edge * must be inside. * @return {nmber} the edge index (index of the starting vertex, so [index,index+1] is the edge ) or -1 if not found. **/ locateEdgeAtPoint(point: XYCoords, tolerance: number): number; }