UNPKG

@zenghawtin/graph2d

Version:

Javascript library for 2d geometry

106 lines (96 loc) 3.3 kB
/** * Created by Alex Bol on 3/12/2017. */ "use strict"; import Flatten from '../flatten'; import IntervalTree from '@flatten-js/interval-tree'; /** * Class representing a planar set - a generic container with ability to keep and retrieve shapes and * perform spatial queries. Planar set is an extension of Set container, so it supports * Set properties and methods */ export class PlanarSet extends Set { /** * Create new instance of PlanarSet * @param shapes - array or set of geometric objects to store in planar set * Each object should have a <b>box</b> property */ constructor(shapes) { super(shapes); this.index = new IntervalTree(); this.forEach(shape => this.index.insert(shape)) } /** * Add new shape to planar set and to its spatial index.<br/> * If shape already exist, it will not be added again. * This happens with no error, it is possible to use <i>size</i> property to check if * a shape was actually added.<br/> * Method returns planar set object updated and may be chained * @param {AnyShape | {Box, AnyShape}} entry - shape to be added, should have valid <i>box</i> property * Another option to transfer as an object {key: Box, value: AnyShape} * @returns {PlanarSet} */ add(entry) { let size = this.size; const {key, value} = entry const box = key || entry.box const shape = value || entry super.add(shape); // size not changed - item not added, probably trying to add same item twice if (this.size > size) { let node = this.index.insert(box, shape); } return this; // in accordance to Set.add interface } /** * Delete shape from planar set. Returns true if shape was actually deleted, false otherwise * @param {AnyShape | {Box, AnyShape}} entry - shape to be deleted * @returns {boolean} */ delete(entry) { const {key, value} = entry const box = key || entry.box const shape = value || entry let deleted = super.delete(shape); if (deleted) { this.index.remove(box, shape); } return deleted; } /** * Clear planar set */ clear() { super.clear(); this.index = new IntervalTree(); } /** * 2d range search in planar set.<br/> * Returns array of all shapes in planar set which bounding box is intersected with query box * @param {Box} box - query box * @returns {AnyShape[]} */ search(box) { let resp = this.index.search(box); return resp; } /** * Point location test. Returns array of shapes which contains given point * @param {Point} point - query point * @returns {AnyShape[]} */ hit(point) { let box = new Flatten.Box(point.x - 1, point.y - 1, point.x + 1, point.y + 1); let resp = this.index.search(box); return resp.filter((shape) => point.on(shape)); } /** * Returns svg string to draw all shapes in planar set * @returns {String} */ svg() { let svgcontent = [...this].reduce((acc, shape) => acc + shape.svg(), ""); return svgcontent; } } Flatten.PlanarSet = PlanarSet;