import RBush from 'rbush'; import type { BoundingBox, CADElement } from '../types/cad.types'; interface IndexedItem extends BoundingBox { element: CADElement; } export class SpatialIndex { private tree: RBush; constructor() { this.tree = new RBush(); } 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, }; } }