| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 | 
							- import H from '../parts/Globals.js';
 
- import '../parts/Utilities.js';
 
- var deg2rad = H.deg2rad,
 
-     find = H.find,
 
-     isArray = H.isArray,
 
-     isNumber = H.isNumber;
 
- /**
 
-  * Alternative solution to correctFloat.
 
-  * E.g H.correctFloat(123, 2) returns 120, when it should be 123.
 
-  *
 
-  * @private
 
-  * @function correctFloat
 
-  *
 
-  * @param {number} number
 
-  *
 
-  * @param {number} precision
 
-  *
 
-  * @return {number}
 
-  */
 
- var correctFloat = function (number, precision) {
 
-     var p = isNumber(precision) ? precision : 14,
 
-         magnitude = Math.pow(10, p);
 
-     return Math.round(number * magnitude) / magnitude;
 
- };
 
- /**
 
-  * Calculates the normals to a line between two points.
 
-  *
 
-  * @private
 
-  * @function getNormals
 
-  *
 
-  * @param {Array<number,number>} p1
 
-  *        Start point for the line. Array of x and y value.
 
-  *
 
-  * @param {Array<number,number>} p2
 
-  *        End point for the line. Array of x and y value.
 
-  *
 
-  * @return {Array<Array<number,number>>}
 
-  *         Returns the two normals in an array.
 
-  */
 
- var getNormals = function getNormal(p1, p2) {
 
-     var dx = p2[0] - p1[0], // x2 - x1
 
-         dy = p2[1] - p1[1]; // y2 - y1
 
-     return [
 
-         [-dy, dx],
 
-         [dy, -dx]
 
-     ];
 
- };
 
- /**
 
-  * Calculates the dot product of two coordinates. The result is a scalar value.
 
-  *
 
-  * @private
 
-  * @function dotProduct
 
-  *
 
-  * @param {Array<number,number>} a
 
-  *        The x and y coordinates of the first point.
 
-  *
 
-  * @param {Array<number,number>} b
 
-  *        The x and y coordinates of the second point.
 
-  *
 
-  * @return {number}
 
-  *         Returns the dot product of a and b.
 
-  */
 
- var dotProduct = function dotProduct(a, b) {
 
-     var ax = a[0],
 
-         ay = a[1],
 
-         bx = b[0],
 
-         by = b[1];
 
-     return ax * bx + ay * by;
 
- };
 
- /**
 
-  * Projects a polygon onto a coordinate.
 
-  *
 
-  * @private
 
-  * @function project
 
-  *
 
-  * @param {Array<Array<number,number>>} polygon
 
-  *        Array of points in a polygon.
 
-  *
 
-  * @param {Array<number,number>} target
 
-  *        The coordinate of pr
 
-  *
 
-  * @return {object}
 
-  */
 
- var project = function project(polygon, target) {
 
-     var products = polygon.map(function (point) {
 
-         return dotProduct(point, target);
 
-     });
 
-     return {
 
-         min: Math.min.apply(this, products),
 
-         max: Math.max.apply(this, products)
 
-     };
 
- };
 
- /**
 
-  * Rotates a point clockwise around the origin.
 
-  *
 
-  * @private
 
-  * @function rotate2DToOrigin
 
-  *
 
-  * @param {Array<number,number>} point
 
-  *        The x and y coordinates for the point.
 
-  *
 
-  * @param {number} angle
 
-  *        The angle of rotation.
 
-  *
 
-  * @return {Array<number,number>}
 
-  *         The x and y coordinate for the rotated point.
 
-  */
 
- var rotate2DToOrigin = function (point, angle) {
 
-     var x = point[0],
 
-         y = point[1],
 
-         rad = deg2rad * -angle,
 
-         cosAngle = Math.cos(rad),
 
-         sinAngle = Math.sin(rad);
 
-     return [
 
-         correctFloat(x * cosAngle - y * sinAngle),
 
-         correctFloat(x * sinAngle + y * cosAngle)
 
-     ];
 
- };
 
- /**
 
-  * Rotate a point clockwise around another point.
 
-  *
 
-  * @private
 
-  * @function rotate2DToPoint
 
-  *
 
-  * @param {Array<number,number>} point
 
-  *        The x and y coordinates for the point.
 
-  *
 
-  * @param {Array<number,numbner>} origin
 
-  *        The point to rotate around.
 
-  *
 
-  * @param {number} angle
 
-  *        The angle of rotation.
 
-  *
 
-  * @return {Array<number,number>}
 
-  *         The x and y coordinate for the rotated point.
 
-  */
 
- var rotate2DToPoint = function (point, origin, angle) {
 
-     var x = point[0] - origin[0],
 
-         y = point[1] - origin[1],
 
-         rotated = rotate2DToOrigin([x, y], angle);
 
-     return [
 
-         rotated[0] + origin[0],
 
-         rotated[1] + origin[1]
 
-     ];
 
- };
 
- var isAxesEqual = function (axis1, axis2) {
 
-     return (
 
-         axis1[0] === axis2[0] &&
 
-         axis1[1] === axis2[1]
 
-     );
 
- };
 
- var getAxesFromPolygon = function (polygon) {
 
-     var points,
 
-         axes = polygon.axes;
 
-     if (!isArray(axes)) {
 
-         axes = [];
 
-         points = points = polygon.concat([polygon[0]]);
 
-         points.reduce(
 
-             function findAxis(p1, p2) {
 
-                 var normals = getNormals(p1, p2),
 
-                     axis = normals[0]; // Use the left normal as axis.
 
-                 // Check that the axis is unique.
 
-                 if (!find(axes, function (existing) {
 
-                     return isAxesEqual(existing, axis);
 
-                 })) {
 
-                     axes.push(axis);
 
-                 }
 
-                 // Return p2 to be used as p1 in next iteration.
 
-                 return p2;
 
-             }
 
-         );
 
-         polygon.axes = axes;
 
-     }
 
-     return axes;
 
- };
 
- var getAxes = function (polygon1, polygon2) {
 
-     // Get the axis from both polygons.
 
-     var axes1 = getAxesFromPolygon(polygon1),
 
-         axes2 = getAxesFromPolygon(polygon2);
 
-     return axes1.concat(axes2);
 
- };
 
- var getPolygon = function (x, y, width, height, rotation) {
 
-     var origin = [x, y],
 
-         left = x - (width / 2),
 
-         right = x + (width / 2),
 
-         top = y - (height / 2),
 
-         bottom = y + (height / 2),
 
-         polygon = [
 
-             [left, top],
 
-             [right, top],
 
-             [right, bottom],
 
-             [left, bottom]
 
-         ];
 
-     return polygon.map(function (point) {
 
-         return rotate2DToPoint(point, origin, -rotation);
 
-     });
 
- };
 
- var getBoundingBoxFromPolygon = function (points) {
 
-     return points.reduce(function (obj, point) {
 
-         var x = point[0],
 
-             y = point[1];
 
-         obj.left = Math.min(x, obj.left);
 
-         obj.right = Math.max(x, obj.right);
 
-         obj.bottom = Math.max(y, obj.bottom);
 
-         obj.top = Math.min(y, obj.top);
 
-         return obj;
 
-     }, {
 
-         left: Number.MAX_VALUE,
 
-         right: -Number.MAX_VALUE,
 
-         bottom: -Number.MAX_VALUE,
 
-         top: Number.MAX_VALUE
 
-     });
 
- };
 
- var isPolygonsOverlappingOnAxis = function (axis, polygon1, polygon2) {
 
-     var projection1 = project(polygon1, axis),
 
-         projection2 = project(polygon2, axis),
 
-         isOverlapping = !(
 
-             projection2.min > projection1.max ||
 
-             projection2.max < projection1.min
 
-         );
 
-     return !isOverlapping;
 
- };
 
- /**
 
-  * Checks wether two convex polygons are colliding by using the Separating Axis
 
-  * Theorem.
 
-  *
 
-  * @private
 
-  * @function isPolygonsColliding
 
-  *
 
-  * @param {Array<Array<number,number>>} polygon1
 
-  *        First polygon.
 
-  *
 
-  * @param {Array<Array<number,number>>} polygon2
 
-  *        Second polygon.
 
-  *
 
-  * @return {boolean}
 
-  *         Returns true if they are colliding, otherwise false.
 
-  */
 
- var isPolygonsColliding = function isPolygonsColliding(polygon1, polygon2) {
 
-     var axes = getAxes(polygon1, polygon2),
 
-         overlappingOnAllAxes = !find(axes, function (axis) {
 
-             return isPolygonsOverlappingOnAxis(axis, polygon1, polygon2);
 
-         });
 
-     return overlappingOnAllAxes;
 
- };
 
- var movePolygon = function (deltaX, deltaY, polygon) {
 
-     return polygon.map(function (point) {
 
-         return [
 
-             point[0] + deltaX,
 
-             point[1] + deltaY
 
-         ];
 
-     });
 
- };
 
- var collision = {
 
-     getBoundingBoxFromPolygon: getBoundingBoxFromPolygon,
 
-     getPolygon: getPolygon,
 
-     isPolygonsColliding: isPolygonsColliding,
 
-     movePolygon: movePolygon,
 
-     rotate2DToOrigin: rotate2DToOrigin,
 
-     rotate2DToPoint: rotate2DToPoint
 
- };
 
- export default collision;
 
 
  |