API Docs for: 0.3.0
Show:

File: modules/Collision/CollisionBox.js

/**
 * @module Collision
 * @namespace Collision
 */

var TW = TW || {};
define([], function() {

	TW.Collision = TW.Collision || {};


	/**
	 * The CollisionBox class allow you to declare a bounding box to test collisions between
	 * other collisions boxes and collisions circles.
	 *
	 * @class CollisionBox
	 * @constructor
	 * @param {Number} x the x coordinate of the collision box
	 * @param {Number} y the y coordinate of the collision box
	 * @param {Number} w the width of the collision box
	 * @param {Number} h the height of the collision box
	 */
	function CollisionBox(x, y, w, h) {

		/**
		 * type of Collision object
		 *
		 * @property {String} type
		 * @readonly
		 */
		this.type = "CollisionBox";

		/**
		 * @property {Number} x
		 */
		this.x = x;

		/**
		 * @property {Number} y
		 */
		this.y = y;

		/**
		 * @property {Number} width
		 */
		this.width = w;

		/**
		 * @property {Number} height
		 */
		this.height = h;
	}


	/**
	 * The isPointInside method allow you to test if a point is inside the bouncing box.
	 *
	 * @method isPointInside
	 * @param {Number} px the x coordinate of the point
	 * @param {Number} py the y coordinate of the point
	 * @return {boolean} true if the point is inside the box, else return false.
	 */
	CollisionBox.prototype.isPointInside = function(px, py) {
		return px >= this.x && px <= this.x + this.width &&
		       py >= this.y && py <= this.y + this.height;
	};

	/**
	 * The isSegmentCollidingCircle method allow you to test if a segment is colliding a circle
	 *
	 * @method isSegmentCollidingCircle
	 * @param {Number} ax the x coordinate of the first point of the segment
	 * @param {Number} ay the y coordinate of the first point of the segment
	 * @param {Number} bx the x coordinate of the second point of the segment
	 * @param {Number} by the y coordinate of the second point of the segment
	 * @param {CollisionCircle} circle the CollisionCircle object to test collision with the segment
	 * @return {boolean} return true if circle and the segment are colliding, else return false.
	 */
	CollisionBox.prototype.isSegmentCollidingCircle = function(ax, ay, bx, by, circle) {
		var vx = bx - ax;
		var vy = by - ay;
		var radius = circle.radius;
		ax -= circle.x;
		ay -= circle.y;
		var delta = (((2 * ax * vx) + (2 * ay * vy)) * ((2 * ax * vx) + (2 * ay * vy))) -
		            (4 * ((vx * vx) + (vy * vy)) * ((ax * ax) + (ay * ay) - (radius * radius)));
		if (delta >= 0) {
			if ((((2 * ax * vx + 2 * ay * vy) * -1) + (Math.sqrt(delta))) / (2 * ((vx * vx) + (vy * vy))) <
			    1.0 &&
			    (((2 * ax * vx + 2 * ay * vy) * -1) + (Math.sqrt(delta))) / (2 * ((vx * vx) + (vy * vy))) >
			    0.0) {
				return true;
			}
			if ((((2 * ax * vx + 2 * ay * vy) * -1) - (Math.sqrt(delta))) / (2 * ((vx * vx) + (vy * vy))) <
			    1.0 &&
			    (((2 * ax * vx + 2 * ay * vy) * -1) - (Math.sqrt(delta))) / (2 * ((vx * vx) + (vy * vy))) >
			    0.0) {
				return true;
			}
		}
		return false;
	};

	/**
	 * The isCollidingCircle method allow you to test if the current CollisionBox
	 * is colliding the CollisionCircle object.
	 *
	 * @method isCollidingCircle
	 * @param {CollisionCircle} circle the CollisionCircle object to test the collision with.
	 * @return {boolean} if the current CollisionBox is colliding the CollisionCircle object,
	 *  then the isCollidingCircle function will return true otherwise it will return false.
	 */
	CollisionBox.prototype.isCollidingCircle = function(circle) {
		var radius = circle.radius;

		//On check si la boite englobante du cercle rentre en collision avec this
		if (circle.x + radius < this.x) {
			return false;
		}
		if (circle.x - radius > this.x + this.width) {
			return false;
		}
		if (circle.y + radius < this.y) {
			return false;
		}
		if (circle.y - radius > this.y + this.height) {
			return false;
		}
		//On check si un des segments de la box rentre en collision avec le cercle
		if (this.isSegmentCollidingCircle(this.x, this.y, this.x + this.width, this.y, circle)) {
			return true;
		}
		if (this.isSegmentCollidingCircle(this.x + this.width, this.y, this.x + this.width, this.y + this.height,
		                                  circle)) {
			return true;
		}
		if (this.isSegmentCollidingCircle(this.x + this.width, this.y + this.height, this.x, this.y + this.height,
		                                  circle)) {
			return true;
		}
		if (this.isSegmentCollidingCircle(this.x, this.y + this.height, this.x, this.y, circle)) {
			return true;
		}
		//On check si le centre du cercle est dans la box.
		if (circle.x > this.x && circle.x < this.x + this.width && circle.y > this.y &&
		    circle.y < this.y + this.height) {
			return true;
		}
		//on check si les sommets de la box sont a une distance plus petite que le rayon du cercle
		if (Math.sqrt(((this.x - circle.x) * (this.x - circle.x)) +
		              ((this.y - circle.y) * (this.y - circle.y))) < radius) {
			return true;
		}
		if (Math.sqrt(((this.x + this.width - circle.x) * (this.x + this.width - circle.x)) +
		              ((this.y - circle.y) * (this.y - circle.y))) < radius) {
			return true;
		}
		if (Math.sqrt(((this.x + this.width - circle.x) * (this.x + this.width - circle.x)) +
		              ((this.y + this.height - circle.y) * (this.y + this.height - circle.y))) < radius) {
			return true;
		}
		if (Math.sqrt(((this.x - circle.x) * (this.x - circle.x)) +
		              ((this.y + this.height - circle.y) * (this.y + this.height - circle.y))) < radius) {
			return true;
		}
		return false;
	};

	/**
	 * The isCollidingBox method allow you to test if the current CollisionBox object is colliding
	 * the CollisionBox object given in parameter.
	 *
	 * @method isCollidingBox
	 * @param {CollisionBox} box the CollisionBox object to test the collision with
	 * @return {Boolean} return true if the box object is colliding the this object.
	 */
	CollisionBox.prototype.isCollidingBox = function(box) {
		if (this.x + this.width < box.x) {
			return false;
		}
		if (this.x > box.x + box.width) {
			return false;
		}
		if (this.y + this.height < box.y) {
			return false;
		}
		return this.y <= box.y + box.height;

	};

	TW.Collision.CollisionBox = CollisionBox;
	return CollisionBox;
});