@thi.ng/geom-accel
Version:
n-D spatial indexing data structures with a shared ES6 Map/Set-like API
154 lines • 5.97 kB
TypeScript
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