UNPKG

quadtree2

Version:

JavaScript implementation of quadtree datastructure for collision detection.

218 lines (162 loc) 5.04 kB
var Quadtree2Quadrant = function Quadtree2Quadrant(leftTop, size, id, parent) { this.leftTop_ = leftTop.clone(); this.children_ = []; this.objects_ = {}; this.objectCount_ = 0; this.id_ = id || 0; this.parent_ = parent; this.refactoring_ = false; this.setSize(size); }; Quadtree2Quadrant.prototype = { setSize : function setSize(size) { if(!size) { return; } this.size_ = size; this.rad_ = size.multiply(0.5, true); this.center_ = this.leftTop_.add(this.rad_, true); this.leftBot_ = this.leftTop_.clone(); this.leftBot_.y += size.y; this.rightTop_ = this.leftTop_.clone(); this.rightTop_.x += size.x; this.rightBot_ = this.leftTop_.add(size, true); this.leftMid_ = this.center_.clone(); this.leftMid_.x = this.leftTop_.x; this.topMid_ = this.center_.clone(); this.topMid_.y = this.leftTop_.y; }, makeChildren : function makeChildren(id) { if (this.children_.length > 0) { return false; } this.children_.push( new Quadtree2Quadrant(this.leftTop_, this.rad_, ++id, this), new Quadtree2Quadrant(this.topMid_, this.rad_, ++id, this), new Quadtree2Quadrant(this.leftMid_, this.rad_, ++id, this), new Quadtree2Quadrant(this.center_, this.rad_, ++id, this) ); return id; }, looseChildren : function looseChildren() { this.children_ = []; }, addObjects : function addObjects(objs) { var id; for (id in objs) { this.addObject(id, objs[id]); } }, addObject : function addObject(id, object) { this.objectCount_++; this.objects_[id] = object; }, removeObjects : function removeObjects(removed, dir) { var id; if (!removed) { removed = []; } for (id in this.objects_) { removed.push({ object : this.objects_[id], quadrant : this }); delete this.objects_[id]; } this.objectCount_ = 0; if (!dir || dir === 1) { if (this.parent_) { this.parent_.removeObjects(removed, 1); } } if (!dir || dir === -1) { this.children_.forEach(function(child) { child.removeObjects(removed, -1); }); } return removed; }, removeObject : function removeObject(id) { var result = this.objects_[id]; this.objectCount_--; delete this.objects_[id]; return result; }, getObjectCountForLimit : function getObjectCountForLimit() { var i, id, objects = {}; for (id in this.objects_) { objects[id] = true; } for (i = 0; i < this.children_.length; i++) { for (id in this.children_[i].objects_) { objects[id] = true; } } return Object.keys(objects).length; }, getObjectCount : function getObjectCount(recursive, onelevel) { var result = this.objectCount_; if (recursive) { this.children_.forEach(function(child) { result += child.getObjectCount(!onelevel && recursive); }); } return result; }, intersectingChildren : function intersectingChildren(pos, rad) { return this.children_.filter(function(child) { return child.intersects(pos, rad); }); }, intersects : function intersects(pos, rad) { var dist = pos.subtract(this.center_, true).abs(), cornerDist; if (dist.x > this.rad_.x + rad) { return false; } if (dist.y > this.rad_.y + rad) { return false; } if (dist.x <= this.rad_.x) { return true; } if (dist.y <= this.rad_.y) { return true; } cornerDistSq = Math.pow(dist.x - this.rad_.x, 2) + Math.pow(dist.y - this.rad_.y, 2); return cornerDistSq <= Math.pow(rad, 2); }, hasChildren : function hasChildren() { return this.getChildCount() !== 0; }, getChildCount : function getChildCount(recursive) { var count = this.children_.length; if (recursive) { this.children_.forEach(function(child) { count += child.getChildCount(recursive); }); } return count; }, getChildren : function getChildren(recursive, result) { if (!result) result = []; result.push.apply(result, this.children_); if (recursive) { this.children_.forEach(function(child) { child.getChildren(recursive, result); }); } return result; }, getObjectsUp : function getObjectsUp(result) { var id; if (result.quadrants[this.id_]) { return; } result.quadrants[this.id_] = true; for (id in this.objects_) { result.objects[id] = this.objects_[id]; } if (this.parent_) { this.parent_.getObjectsUp(result); } }, getObjectsDown : function getObjectsDown(result) { var id; if (result.quadrants[this.id_]) { return; } result.quadrants[this.id_] = true; for (id in this.objects_) { result.objects[id] = this.objects_[id]; } for (id = 0; id < this.children_.length; id++) { this.children_[id].getObjectsDown(result); } return result; } }; module.exports = Quadtree2Quadrant;