"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/** Conversion from Deg to Radiant. */
exports.Deg2Rad = Math.PI / 180; // ~0.017453292
function degToRad(angle) {
    return angle * exports.Deg2Rad;
}
exports.degToRad = degToRad;
/** Conversion from Radiant to Deg. */
exports.Rad2Deg = 180 / Math.PI; // ~57.29577951
function radToDeg(angle) {
    return angle * exports.Rad2Deg;
}
exports.radToDeg = radToDeg;
/**
 * clamps input number to min and max
 * @param input value to clamp
 * @param min
 * @param max
 */
function clamp(input, min, max) {
    if (min > max) {
        console.warn("MathUtils.clamp: min(" + min + ") > max(" + max + ")");
        var tmp = max;
        max = min;
        min = tmp;
    }
    return Math.min(Math.max(input, min), max);
}
exports.clamp = clamp;
/** convenience function checks if numbers are close together */
function isCloseTo(first, second, deviation) {
    if (deviation === void 0) { deviation = 0.01; }
    return Math.abs(first - second) <= deviation;
}
exports.isCloseTo = isCloseTo;
/**
 * converts azimuth (-pi...pi) and elevation (-pi/2...pi/2) to direction vector
 * @param azimuthRad angle from z-axis around y-axis (0 means from front)
 * @param elevationRad angle from z-axis around x-axis (0 means y=0)
 * @param radius radius of polar coordinate (default 1)
 */
function polarToCartRad(azimuthRad, elevationRad, radius) {
    if (radius === void 0) { radius = 1; }
    var result = {
        x: Math.sin(azimuthRad) * Math.cos(elevationRad) * radius,
        y: Math.sin(elevationRad) * radius,
        z: Math.cos(azimuthRad) * Math.cos(elevationRad) * radius,
    };
    return result;
}
exports.polarToCartRad = polarToCartRad;
/**
 * converts azimuth (-180...180) and elevation (-90...90) to direction vector
 * @param azimuthRad angle from z-axis around y-axis (0 means from front)
 * @param elevationRad angle from z-axis around x-axis (0 means y=0)
 * @param radius radius of polar coordinate (default 1)
 */
function polarToCartDeg(azimuthDeg, elevationDeg, radius) {
    return polarToCartRad((azimuthDeg / 180) * Math.PI, (elevationDeg / 180) * Math.PI, radius);
}
exports.polarToCartDeg = polarToCartDeg;
/**
 * converts direction vector to azimuth (-180...180) and elevation (-90...90)
 * @param azimuthRad angle from z-axis around y-axis (0 means from front)
 * @param elevationRad angle from z-axis around x-axis (0 means y=0)
 * @param radius radius of polar coordinate (default 1)
 */
function cartToPolarRad(direction) {
    var length = Math.sqrt(direction.x * direction.x +
        direction.y * direction.y +
        direction.z * direction.z);
    if (length === 0) {
        return {
            azimuth: 0,
            elevation: 0,
            radius: 0,
        };
    }
    var normDir = {
        x: direction.x / length,
        y: direction.y / length,
        z: direction.z / length,
    };
    var xzLength = Math.sqrt(normDir.x * normDir.x + normDir.z * normDir.z) + 1e-8;
    var elevation = Math.asin(normDir.y);
    var azimuth = Math.atan2(normDir.x, normDir.z);
    return {
        azimuth: azimuth,
        elevation: elevation,
        radius: length,
    };
}
exports.cartToPolarRad = cartToPolarRad;
/**
 * converts direction vector to azimuth (-pi...pi) and elevation (-pi/2...pi/2)
 * @param azimuthRad angle from z-axis around y-axis (0 means from front)
 * @param elevationRad angle from z-axis around x-axis (0 means y=0)
 * @param radius radius of polar coordinate (default 1)
 */
function cartToPolarDeg(direction) {
    var resultRad = cartToPolarRad(direction);
    var resultDeg = {
        azimuth: (resultRad.azimuth * 180) / Math.PI,
        elevation: (resultRad.elevation * 180) / Math.PI,
        radius: resultRad.radius,
    };
    return resultDeg;
}
exports.cartToPolarDeg = cartToPolarDeg;
/**
 * The average of all numbers in the array
 * @param array
 * @returns {number}
 */
function arithmeticMean(array) {
    if (!array || array.length === 0) {
        return null;
    }
    return array.reduce(function (prev, current) { return prev + current; }) / array.length;
}
exports.arithmeticMean = arithmeticMean;
/**
 * The median value of the given numbers
 * @param array
 * @returns {number}
 */
function median(array) {
    if (!array || array.length === 0) {
        return null;
    }
    var orderedArray = array.slice().sort();
    var lowerIdx = Math.floor((array.length - 1) / 2);
    var upperIdx = Math.ceil((array.length - 1) / 2);
    return orderedArray[lowerIdx] / 2 + orderedArray[upperIdx] / 2;
}
exports.median = median;
