Repository

js/Mobilizing/core/util/Math.js

/**
* Generates a random number between 2 float values
*
* @param {float} from
* @param {float} to
*/
export function randomFromTo(from, to) {
    return Math.random() * (to - from) + from;
}

/**
* Maps a number between 2 sets of float values
*
* @param {float} value the value to map
* @param {float} low1 the 1st origin value
* @param {float} high1 the 2nd destination value
* @param {float} low2 the 1st destination value
* @param {float} high2
*/
export function map(value, low1, high1, low2, high2) {
    return low2 + (high2 - low2) * (value - low1) / (high1 - low1);
}

/**
* Converts degrees to radians
*
* @param {float} val
*/
export function degToRad(val) {
    const degreeToRadiansFactor = Math.PI / 180;
    return val * degreeToRadiansFactor;
}

/**
* Converts radians to degrees
*
* @param {float} val
*/
export function radToDeg(val) {
    const radianToDegreesFactor = 180 / Math.PI;
    return val * radianToDegreesFactor;
}

/**
* Calculates the distance between two 2D points
*
* @param {float} x1
* @param {float} y1
* @param {float} x2
* @param {float} y2
*/
export function dist(x1, y1, x2, y2) {
    return Math.sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1)));
}

/**
* Lerps a value to the destination value with the given amount
*
* @param {float} value
* @param {float} dest
* @param {float} amount
*/
export function lerp(value, dest, amount) {
    return (value + (dest - value) * amount);
}

/**
* Clamp a value between a minimum and a maximum
*
* @param {Number} value
* @param {Number} min
* @param {Number} max
*/
export function clamp(value, min, max) {
    return (Math.min(max, Math.max(min, value)));
}

/**
* Finds if a point is inside an array of vertices
*
* @param {Number} x
* @param {Number} y
* @param {Vector2 Array} points vertices {x,y}
*/
export function pointIsInside(x, y, points) {
    let i = 0;
    let j = points.length - 1;
    let oddNodes = false;

    for (i = 0; i < points.length; i++) {
        if (points[i].y < y && points[j].y >= y || points[j].y < y && points[i].y >= y) {
            if (points[i].x + (y - points[i].y) / (points[j].y - points[i].y) * (points[j].x - points[i].x) < x) {
                oddNodes = !oddNodes;
            }
        }
        j = i;
    }

    return oddNodes;
}

/**
* Intersection Point between 2 points
* @param  {Array} line1 as [{x,y}, {x,y}]
* @param  {Array} line2 as [{x,y}, {x,y}]
* @return
*/
export function intersectionPoint(line1, line2) {
    const a1 = line1[1].x - line1[0].x;
    const b1 = line2[0].x - line2[1].x;
    const c1 = line2[0].x - line1[0].x;

    const a2 = line1[1].y - line1[0].y;
    const b2 = line2[0].y - line2[1].y;
    const c2 = line2[0].y - line1[0].y;

    let t = 0;
    //treat special case : points are on the same lines!
    if (b1 * c2 === 0 && b2 * c1 === 0 && a2 * b1 === 0 && a1 * b2 === 0) {
        t = 0;
    }
    else {
        t = (b1 * c2 - b2 * c1) / (a2 * b1 - a1 * b2);
    }

    return {
        x: line1[0].x + t * (line1[1].x - line1[0].x),
        y: line1[0].y + t * (line1[1].y - line1[0].y)
    };
}