Files
web-cad/frontend/src/canvas/SpatialIndex.ts
T

49 lines
1.1 KiB
TypeScript

import RBush from 'rbush';
import type { BoundingBox, CADElement } from '../types/cad.types';
interface IndexedItem extends BoundingBox {
element: CADElement;
}
export class SpatialIndex {
private tree: RBush<IndexedItem>;
constructor() {
this.tree = new RBush<IndexedItem>();
}
insert(element: CADElement): void {
const bbox = this.elementBBox(element);
this.tree.insert({ ...bbox, element });
}
bulkInsert(elements: CADElement[]): void {
const items = elements.map(el => ({ ...this.elementBBox(el), element: el }));
this.tree.load(items);
}
search(viewport: BoundingBox): CADElement[] {
return this.tree.search(viewport).map(item => item.element);
}
remove(element: CADElement): void {
const bbox = this.elementBBox(element);
this.tree.remove({ ...bbox, element }, (a, b) => a.element.id === b.element.id);
}
clear(): void {
this.tree.clear();
}
private elementBBox(el: CADElement): BoundingBox {
const halfW = el.width / 2;
const halfH = el.height / 2;
return {
minX: el.x - halfW,
minY: el.y - halfH,
maxX: el.x + halfW,
maxY: el.y + halfH,
};
}
}