UNPKG

@thi.ng/geom-accel

Version:

n-D spatial indexing data structures with a shared ES6 Map/Set-like API

154 lines 5.97 kB
import type { Fn, IEmpty, Predicate2 } from "@thi.ng/api"; import type { INeighborhood } from "@thi.ng/distance"; import type { ReadonlyVec } from "@thi.ng/vectors"; export interface QueryNeighborhoodOpts { /** * Normally the search radius for checking grid cells will be obtained from * the given neighborhood, however this can be overridden via this option. */ r: number; } /** * Abstract base class for an spatially unbounded hash grid. Conceptually * similar to {@link ASpatialGrid}, but using a more efficient internal data * storage and different query API using {@link INeighborhood}s (also see * {@link AHashGrid#queryNeighborhood}). Does not support incremental indexing * or removal of individual items. * * @remarks * Grid data structure based on: * https://matthias-research.github.io/pages/tenMinutePhysics/11-hashing.pdf */ export declare abstract class AHashGrid<T> { invSize: number; tableSize: number; keyFn: Fn<T, ReadonlyVec>; indices: Uint32Array; entries: Uint32Array; items: T[]; constructor(key: Fn<T, ReadonlyVec>, cellSize: number, capacity: number, items?: T[]); get length(): number; clear(): void; /** * Computes number of hash collisions and max cell occupancy. */ stats(): { collisions: number; max: number; }; /** * (Re)builds the hash grid from given items. All previous contents will be * lost! `items` must be less than max. capacity configured via ctor. * * @param items */ build(items: T[]): void; /** * Returns true if an item with given `key` vector has been indexed by the * hash grid. The optional `equiv` predicate can be used to customize the * key equality test (called for all items matching the `keys` hash). * * @remarks * Default predicate is: [thi.ng/vectors * equals()](https://docs.thi.ng/umbrella/vectors/functions/equals.html) * * @param key * @param equiv */ has(key: ReadonlyVec, equiv?: Predicate2<ReadonlyVec>): boolean; /** * Returns array of all items (if any) which have been indexed using given * lookup `key` AND which are passing the given `equiv` predicate (which can * be used to customize the key equality test). * * @remarks * Default predicate is: [thi.ng/vectors * equals()](https://docs.thi.ng/umbrella/vectors/functions/equals.html) * * @param key * @param equiv */ get(key: ReadonlyVec, equiv?: Predicate2<ReadonlyVec>): T[]; /** * Queries grid using provided * [`INeighborhood`](https://docs.thi.ng/umbrella/distance/interfaces/INeighborhood.html) * implementation. Returns neighborhood. * * @example * ```ts tangle:../export/query-neighborhood.ts * import { knearest2 } from "@thi.ng/distance"; * import { HashGrid2 } from "@thi.ng/geom-accel"; * import { repeatedly } from "@thi.ng/transducers"; * import { random2, type ReadonlyVec } from "@thi.ng/vectors"; * * // generate 1000 random points in [-500..500) interval * const pts = [...repeatedly(() => random2([], -500, 500), 1000)]; * * // create hash grid with cell size 16 and index all points * // (since indexed items are just points key function is identity) * const grid = new HashGrid2<ReadonlyVec>((p) => p, 16, pts.length, pts); * * // perform k-nearest neighbor search around origin (k=5, radius=200) * console.log( * grid.queryNeighborhood(knearest2([0, 0], 5, 200)).values() * ); * // [ * // [-12.65, 26.19] * // [1.94, 28.09] * // [-17.49, -8.76] * // [-14.55, 8.17] * // [8.09, 17.47] * // ] * ``` * * @param neighborhood */ abstract queryNeighborhood<N extends INeighborhood<ReadonlyVec, T>>(neighborhood: N, opts?: Partial<QueryNeighborhoodOpts>): N; /** * Returns true if any of the indexed items are located within the given * `neighborhood`. * * @remarks * This method is much faster than {@link AHashGrid.queryNeighborhood} if * one only wants to check if items are present in given region. The method * returns as soon as a positive result is found. * * @param neighborhood * @param opts */ abstract hasNeighborhood<N extends INeighborhood<ReadonlyVec, T>>(neighborhood: N, opts?: Partial<QueryNeighborhoodOpts>): boolean; abstract hashPos(p: ReadonlyVec): number; } /** * 2D implementation of {@link AHashGrid}. */ export declare class HashGrid2<T> extends AHashGrid<T> implements IEmpty<HashGrid2<T>> { empty(): HashGrid2<T>; queryNeighborhood<N extends INeighborhood<ReadonlyVec, T>>(neighborhood: N, opts?: Partial<QueryNeighborhoodOpts>): N; hasNeighborhood<N extends INeighborhood<ReadonlyVec, T>>(neighborhood: N, opts?: Partial<QueryNeighborhoodOpts>): boolean; hashPos(p: ReadonlyVec): number; protected queryBounds<N extends INeighborhood<ReadonlyVec, T>>(neighborhood: N, opts?: Partial<QueryNeighborhoodOpts>): { xmin: number; xmax: number; ymin: number; ymax: number; }; } /** * 3D implementation of {@link AHashGrid}. */ export declare class HashGrid3<T> extends AHashGrid<T> implements IEmpty<HashGrid3<T>> { empty(): HashGrid3<T>; queryNeighborhood<N extends INeighborhood<ReadonlyVec, T>>(neighborhood: N, opts?: Partial<QueryNeighborhoodOpts>): N; hasNeighborhood<N extends INeighborhood<ReadonlyVec, T>>(neighborhood: N, opts?: Partial<QueryNeighborhoodOpts>): boolean; hashPos(p: ReadonlyVec): number; protected queryBounds<N extends INeighborhood<ReadonlyVec, T>>(neighborhood: N, opts?: Partial<QueryNeighborhoodOpts>): { xmin: number; xmax: number; ymin: number; ymax: number; zmin: number; zmax: number; }; } //# sourceMappingURL=hash-grid.d.ts.map