Created
January 28, 2013 17:30
-
-
Save funnylookinhat/4657409 to your computer and use it in GitHub Desktop.
Comparing two class definitions for NodeJS exports.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Static Quad Tree | |
* This is a one-way tree that only allows insertion for maximum efficiency. | |
* @author David Overcash <funnylookinhat@gmail.com> | |
* Credit to https://github.com/mikechambers/ExamplesByMesh for a great example. | |
*/ | |
(function(exports) { | |
var Node = (function (constructParams) { | |
var _MAX_ITEMS = 4; | |
var _quad, | |
_center, | |
_items, | |
_children; | |
__construct = function () { | |
_quad = { | |
xMin: Math.floor(constructParams.quad.xMin), | |
xMax: Math.ceil(constructParams.quad.xMax), | |
yMin: Math.floor(constructParams.quad.yMin), | |
yMax: Math.ceil(constructParams.quad.yMax) | |
}; | |
_center = { | |
x: Math.floor( _quad.xMin + ( ( _quad.xMax - _quad.xMin ) / 2 ) ), | |
y: Math.floor( _quad.yMin + ( ( _quad.yMax - _quad.yMin ) / 2 ) ) | |
} | |
_items = []; | |
_children = null; | |
}() | |
// Determine the index for an item within the quad for this node. | |
// If you want to use Hilbert curves for a radius search or whatnot, you | |
// should change this to return values appropriate to the matrix | |
// [[0,3], | |
// [1,2]] | |
_itemIndex = function (item) { | |
if( item.x < _center.x ) { | |
if( item.y > _center.y ) { | |
return 0; | |
} else { | |
return 1; | |
} | |
} else { | |
if( item.y > _center.y ) { | |
return 3; | |
} else { | |
return 2; | |
} | |
} | |
return ( | |
( item.x < _center.x ? 1 : 0 ) + | |
( 2 * ( item.y < _center.y ? 1 : 0 ) ) | |
); | |
} | |
// Initialize _children and move all items. | |
_generateChildren = function() { | |
_children = []; | |
// Can we speed this up? Or at least make it look nicer? | |
var quads = []; | |
quads.push({xMin: _quad.xMin,xMax: _center.x,yMin: _center.y,yMax: _quad.yMax}); | |
quads.push({xMin: _quad.xMin,xMax: _center.x,yMin: _quad.yMin,yMax: _center.y}); | |
quads.push({xMin: _center.x,xMax: _quad.xMax,yMin: _quad.yMin,yMax: _center.y}); | |
quads.push({xMin: _center.x,xMax: _quad.xMax,yMin: _center.y,yMax: _quad.yMax}); | |
for( i in quads ) { | |
_children[i] = new Node({quad: quads[i]}); | |
} | |
var item = null; | |
while( _items.length ) { | |
item = _items.pop(); | |
_children[_itemIndex(item)].insertItem(item); | |
} | |
_items = null; | |
} | |
this.insertItem = function (item) { | |
if( _children != null ) { | |
if( _children[_itemIndex(item)] == undefined ) { | |
console.log("ERR?"); | |
console.log(_children); | |
} | |
_children[_itemIndex(item)].insertItem(item); | |
} else { | |
_items.push(item); | |
if( _items.length > _MAX_ITEMS ) { | |
_generateChildren(); | |
} | |
} | |
} | |
this.fetchItemsInQuad = function (quad) { | |
var items = []; | |
if( _pointInQuad(_center,quad) ) { | |
if( _items != null ) { | |
items.concat(_items); | |
} else { | |
for( i in _children ) { | |
items.concat(_children[i].fetchItemsInQuad(quad)); | |
} | |
} | |
} | |
return items; | |
} | |
this.totalItems = function () { | |
var count = 0; | |
if( _items != null ) { | |
count += _items.length; | |
} else { | |
for ( i in _children ) { | |
count += _children[i].totalItems(); | |
} | |
} | |
return count; | |
} | |
}); | |
var StaticQuadTree = (function (constructParams) { | |
var _rootNode; | |
_pointInQuad = function(point,quad) { | |
return ( | |
point.x >= quad.xMin && | |
point.x <= quad.xMax && | |
point.y >= quad.yMin && | |
point.y <= quad.yMax | |
); | |
} | |
__construct = function () { | |
if( constructParams.quad == null ) { | |
throw new TypeError("Parameter object must contain object property quad"); | |
} | |
if( constructParams.quad.xMin == null || | |
typeof constructParams.quad.xMin != "number" ) { | |
throw new TypeError("Parameter object quad must contain numeric property xMin"); | |
} | |
if( constructParams.quad.yMin == null || | |
typeof constructParams.quad.yMin != "number" ) { | |
throw new TypeError("Parameter object quad must contain numeric property yMin"); | |
} | |
if( constructParams.quad.xMax == null || | |
typeof constructParams.quad.xMax != "number" ) { | |
throw new TypeError("Parameter object quad must contain numeric property xMax"); | |
} | |
if( constructParams.quad.yMax == null || | |
typeof constructParams.quad.yMax != "number" ) { | |
throw new TypeError("Parameter object quad must contain numeric property yMax"); | |
} | |
_rootNode = new Node({quad: { | |
xMin: constructParams.quad.xMin, | |
xMax: constructParams.quad.xMax, | |
yMin: constructParams.quad.yMin, | |
yMax: constructParams.quad.yMax | |
}}); | |
}() | |
this.insertItem = function (item) { | |
if( typeof item != "object" ) { | |
throw new TypeError("Parameter item must be an object"); | |
} | |
if( item.x == null || | |
typeof item.x != "number" ) { | |
throw new TypeError("Parameter item must contain numeric property x"); | |
} | |
if( item.y == null || | |
typeof item.y != "number" ) { | |
throw new TypeError("Parameter item must container numeric property y"); | |
} | |
_rootNode.insertItem(item); | |
} | |
// TODO | |
this.fetchItemsInQuad = function (quad) { | |
return _rootNode.fetchItemsInQuad(quad); | |
} | |
this.totalItems = function (quad) { | |
return _rootNode.totalItems(); | |
} | |
}); | |
exports.StaticQuadTree = StaticQuadTree; | |
})(typeof global === "undefined" ? window : exports); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Static Quad Tree | |
* This is a one-way tree that only allows insertion for maximum efficiency. | |
* @author David Overcash <funnylookinhat@gmail.com> | |
* Credit to https://github.com/mikechambers/ExamplesByMesh for a great example. | |
*/ | |
(function(exports) { | |
var Node = function (xMin,xMax,yMin,yMax,level) { | |
this._quad = { | |
xMin: xMin, | |
xMax: xMax, | |
yMin: yMin, | |
yMax: yMax | |
}; | |
this._center = { | |
x: Math.floor( this._quad.xMin + ( ( this._quad.xMax - this._quad.xMin ) / 2 ) ), | |
y: Math.floor( this._quad.yMin + ( ( this._quad.yMax - this._quad.yMin ) / 2 ) ) | |
} | |
this._items = []; | |
this._children = null; | |
if( level != null ) { | |
this._level = level; | |
} else { | |
this._level = 0; | |
} | |
} | |
Node.MAX_ITEMS = 4; | |
Node.MAX_LEVEL = 4; | |
Node._pointInQuad = function(point,quad) { | |
return ( | |
point.x >= quad.xMin && | |
point.x <= quad.xMax && | |
point.y >= quad.yMin && | |
point.y <= quad.yMax | |
); | |
} | |
Node.prototype._intersectsQuad = function (quad) { | |
return ( ( | |
this._quad.xMin > quad.xMax || | |
this._quad.xMax < quad.xMin || | |
this._quad.yMin > quad.yMax || | |
this._quad.yMax < quad.yMin | |
) ? false : true ); | |
} | |
Node.prototype._containedInQuad = function (quad) { | |
return ( ( | |
this._quad.xMin >= quad.xMin && | |
this._quad.xMax <= quad.xMax && | |
this._quad.yMin >= quad.yMin && | |
this._quad.yMax <= quad.yMax | |
) ? true : false ); | |
} | |
Node.prototype._itemIndex = function (item) { | |
if( item.y < this._center.y ) { | |
if( item.x < this._center.x ) { | |
return 1; | |
} | |
return 2; | |
} else { | |
if( item.x < this._center.x ) { | |
return 0; | |
} | |
return 3; | |
} | |
/* | |
return ( | |
( item.y < this._center.y ? 1 : 0 ) + | |
( item.x < this._center.x ? 0 : 2 ) | |
); | |
*/ | |
} | |
Node.prototype._generateChildren = function() { | |
this._children = []; | |
// Can we speed this up? Or at least make it look nicer? | |
this._children[0] = new Node(this._quad.xMin, this._center.x, this._center.y, this._quad.yMax, (this._level + 1)); | |
this._children[1] = new Node(this._quad.xMin, this._center.x, this._quad.yMin, this._center.y, (this._level + 1)); | |
this._children[2] = new Node(this._center.x, this._quad.xMax, this._quad.yMin, this._center.y, (this._level + 1)); | |
this._children[3] = new Node(this._center.x, this._quad.xMax, this._center.y, this._quad.yMax, (this._level + 1)); | |
var item = null; | |
while( this._items.length ) { | |
item = this._items.pop(); | |
this._children[this._itemIndex(item)].insertItem(item); | |
} | |
_items = null; | |
} | |
Node.prototype.insertItem = function (item) { | |
if( this._children != null ) { | |
this._children[this._itemIndex(item)].insertItem(item); | |
} else { | |
this._items.push(item); | |
if( ( | |
! Node.MAX_LEVEL || | |
this._level < Node.MAX_LEVEL | |
) && | |
this._items.length > Node.MAX_ITEMS ) { | |
this._generateChildren(); | |
} | |
} | |
} | |
Node.prototype.fetchAllItems = function () { | |
var items = []; | |
if( this._items != null ) { | |
items = items.concat(this._items); | |
} | |
if( this._children != null ) { | |
for( i in this._children ) { | |
items = items.concat(this._children[i].fetchAllItems()); | |
} | |
} | |
return items; | |
} | |
Node.prototype.fetchItemsInQuad = function (quad) { | |
var items = []; | |
if( this._intersectsQuad(quad) ) { | |
if( this._items != null ) { | |
items = items.concat(this._items); | |
} | |
if( this._children != null ) { | |
if( this._containedInQuad(quad) ) { | |
for( i in this._children ) { | |
items = items.concat(this._children[i].fetchAllItems()); | |
} | |
} else { | |
for( i in this._children ) { | |
items = items.concat(this._children[i].fetchItemsInQuad(quad)); | |
} | |
} | |
} | |
} | |
return items; | |
} | |
Node.prototype.totalItems = function () { | |
var count = this._items.length; | |
if( this._children != null ) { | |
for ( i in this._children ) { | |
count += this._children[i].totalItems(); | |
} | |
} | |
return count; | |
} | |
Node.prototype.dumpTree = function (level) { | |
console.log('NODE: x={'+this._quad.xMin+':'+this._quad.xMax+'} y={'+this._quad.yMin+':'+this._quad.yMax+'}'+' ITEMS: '+this._items.length); | |
if( this._children != null ) { | |
for( i in this._children ) { | |
console.log(level); | |
this._children[i].dumpTree((level+'-')); | |
} | |
} | |
} | |
var StaticQuadTree = function (xMin,xMax,yMin,yMax) { | |
if( xMin == null || | |
typeof xMin != "number" ) { | |
throw new TypeError("xMin must be numeric."); | |
} | |
if( yMin == null || | |
typeof yMin != "number" ) { | |
throw new TypeError("yMin must be numeric."); | |
} | |
if( xMax == null || | |
typeof xMax != "number" ) { | |
throw new TypeError("xMax must be numeric."); | |
} | |
if( yMax == null || | |
typeof yMax != "number" ) { | |
throw new TypeError("yMax must be numeric."); | |
} | |
this._rootNode = new Node(xMin, xMax, yMin, yMax); | |
} | |
StaticQuadTree.prototype.insertItem = function (item) { | |
if( typeof item != "object" ) { | |
throw new TypeError("Parameter item must be an object"); | |
} | |
if( item.x == null || | |
typeof item.x != "number" ) { | |
throw new TypeError("Parameter item must contain numeric property x"); | |
} | |
if( item.y == null || | |
typeof item.y != "number" ) { | |
throw new TypeError("Parameter item must container numeric property y"); | |
} | |
this._rootNode.insertItem(item); | |
} | |
StaticQuadTree.prototype.fetchItemsInQuad = function (xMin,xMax,yMin,yMax) { | |
var quad = { | |
xMin: xMin, | |
xMax: xMax, | |
yMin: yMin, | |
yMax: yMax | |
} | |
return this._rootNode.fetchItemsInQuad(quad); | |
} | |
StaticQuadTree.prototype.totalItems = function() { | |
return this._rootNode.totalItems(); | |
} | |
StaticQuadTree.prototype.dumpTree = function() { | |
this._rootNode.dumpTree('-'); | |
} | |
exports.Node = Node; | |
exports.StaticQuadTree = StaticQuadTree; | |
})(typeof global === "undefined" ? window : exports); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment