123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- /* *
- *
- * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
- *
- * */
- import H from '../Core/Globals.js';
- /**
- * @private
- * @interface Highcharts.PolygonPointObject
- */ /**
- * @name Highcharts.PolygonPointObject#0
- * @type {number}
- */ /**
- * @name Highcharts.PolygonPointObject#1
- * @type {number}
- */
- /**
- * @private
- * @interface Highcharts.PolygonObject
- * @extends Array<Highcharts.PolygonPointObject>
- */ /**
- * @name Highcharts.PolygonObject#axes
- * @type {Array<PolygonPointObject>}
- */
- import U from '../Core/Utilities.js';
- var find = U.find, isArray = U.isArray, isNumber = U.isNumber;
- var deg2rad = H.deg2rad;
- /* eslint-disable no-invalid-this, valid-jsdoc */
- /**
- * Alternative solution to correctFloat.
- * E.g Highcharts.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 {Highcharts.PolygonPointObject} p1
- * Start point for the line. Array of x and y value.
- * @param {Highcharts.PolygonPointObject} p2
- * End point for the line. Array of x and y value.
- * @return {Highcharts.PolygonObject}
- * 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 {Highcharts.PolygonPointObject} a
- * The x and y coordinates of the first point.
- *
- * @param {Highcharts.PolygonPointObject} 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 {Highcharts.PolygonObject} polygon
- * Array of points in a polygon.
- * @param {Highcharts.PolygonPointObject} target
- * The coordinate of pr
- * @return {Highcharts.RangeObject}
- */
- 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 {Highcharts.PolygonPointObject} point
- * The x and y coordinates for the point.
- * @param {number} angle
- * The angle of rotation.
- * @return {Highcharts.PolygonPointObject}
- * 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 {Highcharts.PolygonPointObject} point
- * The x and y coordinates for the point.
- * @param {Highcharts.PolygonPointObject} origin
- * The point to rotate around.
- * @param {number} angle
- * The angle of rotation.
- * @return {Highcharts.PolygonPointObject}
- * 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]
- ];
- };
- /**
- * @private
- */
- var isAxesEqual = function (axis1, axis2) {
- return (axis1[0] === axis2[0] &&
- axis1[1] === axis2[1]);
- };
- /**
- * @private
- */
- 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;
- };
- /**
- * @private
- */
- var getAxes = function (polygon1, polygon2) {
- // Get the axis from both polygons.
- var axes1 = getAxesFromPolygon(polygon1), axes2 = getAxesFromPolygon(polygon2);
- return axes1.concat(axes2);
- };
- /**
- * @private
- */
- 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);
- });
- };
- /**
- * @private
- */
- 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
- });
- };
- /**
- * @private
- */
- 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 {Highcharts.PolygonObject} polygon1
- * First polygon.
- *
- * @param {Highcharts.PolygonObject} 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;
- };
- /**
- * @private
- */
- 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;
|