From c6b15b065897e167d043f4868f86d14cf47b5d28 Mon Sep 17 00:00:00 2001 From: Mark Date: Wed, 8 Feb 2012 14:25:35 +0200 Subject: [PATCH 1/3] Fixed subdivide to pass maxChildren and maxDepth to newly created nodes. Replaced `window` with `this` in order to make QuadTree available in node.js by `require()` --- JavaScript/QuadTree/src/QuadTree.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/JavaScript/QuadTree/src/QuadTree.js b/JavaScript/QuadTree/src/QuadTree.js index 49819ad..f194b3d 100644 --- a/JavaScript/QuadTree/src/QuadTree.js +++ b/JavaScript/QuadTree/src/QuadTree.js @@ -255,7 +255,7 @@ Node.prototype.subdivide = function() width:b_w_h, height:b_h_h }, - depth); + depth, this._maxDepth, this._maxChildren); //top right this.nodes[Node.TOP_RIGHT] = new this._classConstructor({ @@ -264,7 +264,7 @@ Node.prototype.subdivide = function() width:b_w_h, height:b_h_h }, - depth); + depth, this._maxDepth, this._maxChildren); //bottom left this.nodes[Node.BOTTOM_LEFT] = new this._classConstructor({ @@ -273,7 +273,7 @@ Node.prototype.subdivide = function() width:b_w_h, height:b_h_h }, - depth); + depth, this._maxDepth, this._maxChildren); //bottom right @@ -283,7 +283,7 @@ Node.prototype.subdivide = function() width:b_w_h, height:b_h_h }, - depth); + depth, this._maxDepth, this._maxChildren); } Node.prototype.clear = function() @@ -428,4 +428,4 @@ if ( typeof Object.getPrototypeOf !== "function" ) { } */ -}(window)); \ No newline at end of file +}(this)); \ No newline at end of file From 2e82d7bb054ff059354a976fdbfe0d741f02c0bb Mon Sep 17 00:00:00 2001 From: Mark Date: Wed, 8 Feb 2012 16:31:38 +0200 Subject: [PATCH 2/3] added retrieveInBounds method that returns points found in specified bounds --- JavaScript/QuadTree/src/QuadTree.js | 74 +++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/JavaScript/QuadTree/src/QuadTree.js b/JavaScript/QuadTree/src/QuadTree.js index f194b3d..2758ba1 100644 --- a/JavaScript/QuadTree/src/QuadTree.js +++ b/JavaScript/QuadTree/src/QuadTree.js @@ -113,6 +113,37 @@ QuadTree.prototype.retrieve = function(item) return out; } +QuadTree.prototype.retrieveInBounds = function (bounds) +{ + if(this.root instanceof BoundsNode) + { + throw 'Not implemented'; + } + + var treeResult = this.root.retrieveInBounds(bounds); + var filteredResult = []; + + for (var i=0; i < treeResult.length; i++) + { + var point = treeResult[i]; + if(_isPointInsideBounds(point, bounds)) + { + filteredResult.push(point); + } + } + return filteredResult; +} + +var _isPointInsideBounds = function (point, bounds) +{ + return ( + (point.x >= bounds.x) && + (point.x <= bounds.x + bounds.width) && + (point.y >= bounds.y) && + (point.y <= bounds.y + bounds.height) + ); +} + /************** Node ********************/ @@ -199,6 +230,49 @@ Node.prototype.retrieve = function(item) return this.children; } +Node.prototype.retrieveInBounds = function(bounds) +{ + if(!this.collidesWith(bounds)) + { + return []; + } + + if(this.children.length) + { + return this.children; + } + else + { + if(this.nodes.length) + { + var result = []; + for (var i = 0; i < this.nodes.length; i++) + { + result = result.concat(this.nodes[i].retrieveInBounds(bounds)); + } + return result; + } + else + { + return []; + } + } +} + + +Node.prototype.collidesWith = function (bounds) +{ + var b1 = this._bounds; + var b2 = bounds; + + return !( + b1.x > (b2.x + b2.width) || + b2.x > (b1.x + b1.width) || + b1.y > (b2.y + b2.height) || + b2.y > (b1.y + b1.height) + ); +} + Node.prototype._findIndex = function(item) { var b = this._bounds; From c9a00d2cb6a0edee16c918fe961acf392ec7f094 Mon Sep 17 00:00:00 2001 From: Will Date: Fri, 9 Mar 2012 15:46:52 +1300 Subject: [PATCH 3/3] retrieveInBounds now supports non-point (bounds) QuadTrees --- JavaScript/QuadTree/src/QuadTree.js | 79 +++++++++++++++++++---------- 1 file changed, 52 insertions(+), 27 deletions(-) diff --git a/JavaScript/QuadTree/src/QuadTree.js b/JavaScript/QuadTree/src/QuadTree.js index 2758ba1..9aacaea 100644 --- a/JavaScript/QuadTree/src/QuadTree.js +++ b/JavaScript/QuadTree/src/QuadTree.js @@ -110,31 +110,47 @@ QuadTree.prototype.retrieve = function(item) { //get a copy of the array of items var out = this.root.retrieve(item).slice(0); + //return QuadTree._filterResults(out, {x:item.x, y:item.y, width:0, height:0}); return out; } QuadTree.prototype.retrieveInBounds = function (bounds) { - if(this.root instanceof BoundsNode) - { - throw 'Not implemented'; - } - var treeResult = this.root.retrieveInBounds(bounds); + return QuadTree._filterResults(treeResult, bounds); +} + +QuadTree._filterResults = function(treeResult, bounds) +{ var filteredResult = []; - for (var i=0; i < treeResult.length; i++) + if(this.root instanceof BoundsNode) + { + for (var i=0; i < treeResult.length; i++) + { + var node = treeResult[i]; + if (QuadTree._isBoundOverlappingBound(node, bounds)) + { + filteredResult.push(node); + } + } + } + else { - var point = treeResult[i]; - if(_isPointInsideBounds(point, bounds)) + for (var i=0; i < treeResult.length; i++) { - filteredResult.push(point); + var node = treeResult[i]; + if(QuadTree._isPointInsideBounds(node, bounds)) + { + filteredResult.push(node); + } } } + return filteredResult; } -var _isPointInsideBounds = function (point, bounds) +QuadTree._isPointInsideBounds = function (point, bounds) { return ( (point.x >= bounds.x) && @@ -144,6 +160,17 @@ var _isPointInsideBounds = function (point, bounds) ); } + +QuadTree._isBoundOverlappingBound = function (b1, b2) +{ + return !( + b1.x > (b2.x + b2.width) || + b2.x > (b1.x + b1.width) || + b1.y > (b2.y + b2.height) || + b2.y > (b1.y + b1.height) + ); +} + /************** Node ********************/ @@ -232,31 +259,29 @@ Node.prototype.retrieve = function(item) Node.prototype.retrieveInBounds = function(bounds) { - if(!this.collidesWith(bounds)) - { - return []; - } + var result = []; - if(this.children.length) + if(this.collidesWith(bounds)) { - return this.children; - } - else - { - if(this.nodes.length) + result = result.concat(this._stuckChildren); + + if(this.children.length) { - var result = []; - for (var i = 0; i < this.nodes.length; i++) - { - result = result.concat(this.nodes[i].retrieveInBounds(bounds)); - } - return result; + result = result.concat(this.children); } else { - return []; + if(this.nodes.length) + { + for (var i = 0; i < this.nodes.length; i++) + { + result = result.concat(this.nodes[i].retrieveInBounds(bounds)); + } + } } } + + return result; }