import { create, Point } from '../vector'; import { assert } from './langUtil'; export const EDGE_TYPE_MAPPING = 1; export const EDGE_TYPE_DEGENERACY = 2; export type EdgeType = typeof EDGE_TYPE_MAPPING | typeof EDGE_TYPE_DEGENERACY; export default class SkeletonNode { p: Point = create(); outgoingEdges: Map = new Map(); incomingEdges: Map = new Map(); private _reflex = false; constructor() {} /** * Marks this SkeletonNode as connected to a reflex vertex. */ setReflex() { this._reflex = true; } /** * @return Whether this SkeletonNode is connected to a reflex vertex. */ isReflex() { return this._reflex; } addEdge(target: SkeletonNode) { this._addEdge(target, EDGE_TYPE_MAPPING); } // TODO: This should be a different type of edge? It doesn't map an initial vertex to another SkeletonNode. The mapping should stay. // Edges from degeneration don't continue mapping of initial vertices. Degeneration = stop moving inwards, only connect inner skeleton nodes. addDegenerationEdge(target: SkeletonNode) { this._addEdge(target, EDGE_TYPE_DEGENERACY); } private _addEdge(target: SkeletonNode, type: EdgeType) { this.outgoingEdges.set(target, type); target.incomingEdges.set(this, type); } remapIncoming(newTarget: SkeletonNode) { assert(this.outgoingEdges.size === 0); this.incomingEdges.forEach((edgeType, node) => { node.outgoingEdges.delete(this); node._addEdge(newTarget, edgeType); }); this.incomingEdges.clear(); } followGraphInward(storeTargets: SkeletonNode[]) { let leaf = true; this.outgoingEdges.forEach((edgeType, node) => { if (edgeType === EDGE_TYPE_MAPPING) { node.followGraphInward(storeTargets); leaf = false; } /*else { storeTargets.add(entry.getKey()); }*/ }); if (leaf) { storeTargets.push(this); } } }