UNPKG

2d-physics-engine

Version:

A lightweight, flexible 2D physics engine with ECS architecture, built with TypeScript

88 lines 2.95 kB
import { AABB } from './AABB'; import { Vector2 } from './Vector2'; export class QuadTree { constructor(aabb, maxObjects) { Object.defineProperty(this, "aabb", { enumerable: true, configurable: true, writable: true, value: aabb }); Object.defineProperty(this, "maxObjects", { enumerable: true, configurable: true, writable: true, value: maxObjects }); Object.defineProperty(this, "points", { enumerable: true, configurable: true, writable: true, value: [] }); Object.defineProperty(this, "nodes", { enumerable: true, configurable: true, writable: true, value: null }); } /** Inserts a point into the quadtree. */ insert(point) { if (!this.aabb.containsPoint(point)) { return false; } if (this.points.length < this.maxObjects) { this.points.push(point); return true; } if (!this.nodes) { this.subdivide(); } if (this.nodes?.get('NE')?.insert(point) || this.nodes?.get('SE')?.insert(point) || this.nodes?.get('SW')?.insert(point) || this.nodes?.get('NW')?.insert(point)) { return true; } return false; } /** Subdivides the current node into four child nodes. */ subdivide() { const { x, y } = this.aabb.center; const width = this.aabb.width / 2; const height = this.aabb.height / 2; this.nodes = new Map([ ['NE', new QuadTree(new AABB(new Vector2(x, y - height), new Vector2(x + width, y)), this.maxObjects)], ['SE', new QuadTree(new AABB(new Vector2(x, y), new Vector2(x + width, y + height)), this.maxObjects)], ['SW', new QuadTree(new AABB(new Vector2(x - width, y), new Vector2(x, y + height)), this.maxObjects)], ['NW', new QuadTree(new AABB(new Vector2(x - width, y - height), new Vector2(x, y)), this.maxObjects)], ]); } /** Query points within a range. */ query(range, foundPoints = []) { // If the range doesn't intersect this node, return if (!this.aabb.intersects(range)) { return foundPoints; } // Check points in this node for (const point of this.points) { if (range.containsPoint(point)) { foundPoints.push(point); } } // Recursively check child nodes if (this.nodes) { for (const node of this.nodes.values()) { node.query(range, foundPoints); } } return foundPoints; } /** Clears the quadtree. */ clear() { this.points = []; this.nodes = null; } } //# sourceMappingURL=QuadTree.js.map