UNPKG

uplot-vplugins

Version:
109 lines (95 loc) 1.98 kB
export function pointWithin(px, py, rlft, rtop, rrgt, rbtm) { return px >= rlft && px <= rrgt && py >= rtop && py <= rbtm; } const MAX_OBJECTS = 10; const MAX_LEVELS = 4; export class Quadtree { constructor(x: number, y: number, w: number, h: number, l?: number) { this.x = x; this.y = y; this.w = w; this.h = h; this.l = l || 0; this.o = []; this.q = null; } x: number; y: number; w: number; h: number; l: number; o: any[]; q: any; split() { const t = this, x = t.x, y = t.y, w = t.w / 2, h = t.h / 2, l = t.l + 1; t.q = [ // top right new Quadtree(x + w, y, w, h, l), // top left new Quadtree(x, y, w, h, l), // bottom left new Quadtree(x, y + h, w, h, l), // bottom right new Quadtree(x + w, y + h, w, h, l), ]; } // invokes callback with index of each overlapping quad quads(x, y, w, h, cb) { const t = this, q = t.q, hzMid = t.x + t.w / 2, vtMid = t.y + t.h / 2, startIsNorth = y < vtMid, startIsWest = x < hzMid, endIsEast = x + w > hzMid, endIsSouth = y + h > vtMid; // top-right quad startIsNorth && endIsEast && cb(q[0]); // top-left quad startIsWest && startIsNorth && cb(q[1]); // bottom-left quad startIsWest && endIsSouth && cb(q[2]); // bottom-right quad endIsEast && endIsSouth && cb(q[3]); } add(o) { const t = this; if (t.q != null) { t.quads(o.x, o.y, o.w, o.h, q=>{ q.add(o); }); } else { const os = t.o; os.push(o); if (os.length > MAX_OBJECTS && t.l < MAX_LEVELS) { t.split(); for (let i = 0; i < os.length; i++) { const oi = os[i]; t.quads(oi.x, oi.y, oi.w, oi.h, q=>{ q.add(oi); }); } t.o.length = 0; } } } get(x, y, w, h, cb) { const t = this; const os = t.o; for (let i = 0; i < os.length; i++) cb(os[i]); if (t.q != null) { t.quads(x, y, w, h, q=>{ q.get(x, y, w, h, cb); }); } } clear() { this.o.length = 0; this.q = null; } }