File: src/collision/AABB.js
var vec2 = require('../math/vec2')
, Utils = require('../utils/Utils');
module.exports = AABB;
/**
* Axis aligned bounding box class.
* @class AABB
* @constructor
* @param {Object} [options]
* @param {Array} [options.upperBound]
* @param {Array} [options.lowerBound]
*/
function AABB(options){
/**
* The lower bound of the bounding box.
* @property lowerBound
* @type {Array}
*/
this.lowerBound = vec2.create();
if(options && options.lowerBound){
vec2.copy(this.lowerBound, options.lowerBound);
}
/**
* The upper bound of the bounding box.
* @property upperBound
* @type {Array}
*/
this.upperBound = vec2.create();
if(options && options.upperBound){
vec2.copy(this.upperBound, options.upperBound);
}
}
var tmp = vec2.create();
/**
* Set the AABB bounds from a set of points.
* @method setFromPoints
* @param {Array} points An array of vec2's.
*/
AABB.prototype.setFromPoints = function(points,position,angle){
var l = this.lowerBound,
u = this.upperBound;
vec2.set(l, Number.MAX_VALUE, Number.MAX_VALUE);
vec2.set(u, -Number.MAX_VALUE, -Number.MAX_VALUE);
for(var i=0; i<points.length; i++){
var p = points[i];
if(typeof(angle) === "number"){
vec2.rotate(tmp,p,angle);
p = tmp;
}
for(var j=0; j<2; j++){
if(p[j] > u[j]){
u[j] = p[j];
}
if(p[j] < l[j]){
l[j] = p[j];
}
}
}
// Add offset
if(position){
vec2.add(this.lowerBound, this.lowerBound, position);
vec2.add(this.upperBound, this.upperBound, position);
}
};
/**
* Copy bounds from an AABB to this AABB
* @method copy
* @param {AABB} aabb
*/
AABB.prototype.copy = function(aabb){
vec2.copy(this.lowerBound, aabb.lowerBound);
vec2.copy(this.upperBound, aabb.upperBound);
};
/**
* Extend this AABB so that it covers the given AABB too.
* @method extend
* @param {AABB} aabb
*/
AABB.prototype.extend = function(aabb){
// Loop over x and y
for(var i=0; i<2; i++){
// Extend lower bound
if(aabb.lowerBound[i] < this.lowerBound[i]){
this.lowerBound[i] = aabb.lowerBound[i];
}
// Upper
if(aabb.upperBound[i] > this.upperBound[i]){
this.upperBound[i] = aabb.upperBound[i];
}
}
};
/**
* Returns true if the given AABB overlaps this AABB.
* @method overlaps
* @param {AABB} aabb
* @return {Boolean}
*/
AABB.prototype.overlaps = function(aabb){
var l1 = this.lowerBound,
u1 = this.upperBound,
l2 = aabb.lowerBound,
u2 = aabb.upperBound;
// l2 u2
// |---------|
// |--------|
// l1 u1
return ((l2[0] <= u1[0] && u1[0] <= u2[0]) || (l1[0] <= u2[0] && u2[0] <= u1[0])) &&
((l2[1] <= u1[1] && u1[1] <= u2[1]) || (l1[1] <= u2[1] && u2[1] <= u1[1]));
};