# all files / ol/ math.js

95.38% Statements 62/65
83.33% Branches 15/18
100% Functions 9/9
95.38% Lines 62/65

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    1821×

    1×

    1×
    7541×

    1×

    1×
    1×

    1×
    595×
    595×

    1×

    1×
    19×
    17×

    1×
    1750×
    1750×
    1750×
    1745×
    1745×

    1745×
    1741×
    1741×

    1750×

    1×
    2432×
    2432×
    2432×

    1×
    206×

    206×
    206×
    820×

    204×

    814×
    814×
    814×
    1218×
    1218×
    1×
    1×

    814×
    1×

    813×
    813×
    813×

    813×
    1218×
    1218×
    5274×
    1218×

    4056×

    203×
    203×
    811×
    811×
    1215×

    203×

    1×
    3×

    1×
    4077×

     goog.provide('ol.math');

    goog.require('goog.asserts');

    /**
     * Takes a number and clamps it to within the provided bounds.
     * @param {number} value The input number.
     * @param {number} min The minimum value to return.
     * @param {number} max The maximum value to return.
     * @return {number} The input number if it is within bounds, or the nearest
     *     number within the bounds.
     */
    ol.math.clamp = function(value, min, max) {
      return Math.min(Math.max(value, min), max);
    };

    /**
     * Return the hyperbolic cosine of a given number. The method will use the
     * native `Math.cosh` function if it is available, otherwise the hyperbolic
     * cosine will be calculated via the reference implementation of the Mozilla
     * developer network.
     *
     * @param {number} x X.
     * @return {number} Hyperbolic cosine of x.
     */
    ol.math.cosh = (function() {
      // Wrapped in a iife, to save the overhead of checking for the native
      // implementation on every invocation.
      var cosh;
      Iif ('cosh' in Math) {
        // The environment supports the native Math.cosh function, use it…
        cosh = Math.cosh;
      } else {
        // … else, use the reference implementation of MDN:
        cosh = function(x) {
          var y = Math.exp(x);
          return (y + 1 / y) / 2;
        };
      }
      return cosh;
    }());

    /**
     * @param {number} x X.
     * @return {number} The smallest power of two greater than or equal to x.
     */
    ol.math.roundUpToPowerOfTwo = function(x) {
      goog.asserts.assert(0 < x, 'x should be larger than 0');
      return Math.pow(2, Math.ceil(Math.log(x) / Math.LN2));
    };

    /**
     * Returns the square of the closest distance between the point (x, y) and the
     * line segment (x1, y1) to (x2, y2).
     * @param {number} x X.
     * @param {number} y Y.
     * @param {number} x1 X1.
     * @param {number} y1 Y1.
     * @param {number} x2 X2.
     * @param {number} y2 Y2.
     * @return {number} Squared distance.
     */
    ol.math.squaredSegmentDistance = function(x, y, x1, y1, x2, y2) {
      var dx = x2 - x1;
      var dy = y2 - y1;
      if (dx !== 0 || dy !== 0) {
        var t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy);
        Iif (t > 1) {
          x1 = x2;
          y1 = y2;
        } else if (t > 0) {
          x1 += dx * t;
          y1 += dy * t;
        }
      }
      return ol.math.squaredDistance(x, y, x1, y1);
    };

    /**
     * Returns the square of the distance between the points (x1, y1) and (x2, y2).
     * @param {number} x1 X1.
     * @param {number} y1 Y1.
     * @param {number} x2 X2.
     * @param {number} y2 Y2.
     * @return {number} Squared distance.
     */
    ol.math.squaredDistance = function(x1, y1, x2, y2) {
      var dx = x2 - x1;
      var dy = y2 - y1;
      return dx * dx + dy * dy;
    };

    /**
     * Solves system of linear equations using Gaussian elimination method.
     *
     * @param {Array.<Array.<number>>} mat Augmented matrix (n x n + 1 column)
     *                                     in row-major order.
     * @return {Array.<number>} The resulting vector.
     */
    ol.math.solveLinearSystem = function(mat) {
      var n = mat.length;

      Eif (goog.asserts.ENABLE_ASSERTS) {
        for (var row = 0; row < n; row++) {
          goog.asserts.assert(mat[row].length == n + 1,
                              'every row should have correct number of columns');
        }
      }

      for (var i = 0; i < n; i++) {
        // Find max in the i-th column (ignoring i - 1 first rows)
        var maxRow = i;
        var maxEl = Math.abs(mat[i][i]);
        for (var r = i + 1; r < n; r++) {
          var absValue = Math.abs(mat[r][i]);
          if (absValue > maxEl) {
            maxEl = absValue;
            maxRow = r;
          }
        }

        if (maxEl === 0) {
          return null; // matrix is singular
        }

        // Swap max row with i-th (current) row
        var tmp = mat[maxRow];
        mat[maxRow] = mat[i];
        mat[i] = tmp;

        // Subtract the i-th row to make all the remaining rows 0 in the i-th column
        for (var j = i + 1; j < n; j++) {
          var coef = -mat[j][i] / mat[i][i];
          for (var k = i; k < n + 1; k++) {
            if (i == k) {
              mat[j][k] = 0;
            } else {
              mat[j][k] += coef * mat[i][k];
            }
          }
        }
      }

      // Solve Ax=b for upper triangular matrix A (mat)
      var x = new Array(n);
      for (var l = n - 1; l >= 0; l--) {
        x[l] = mat[l][n] / mat[l][l];
        for (var m = l - 1; m >= 0; m--) {
          mat[m][n] -= mat[m][l] * x[l];
        }
      }
      return x;
    };

    /**
     * Converts radians to to degrees.
     *
     * @param {number} angleInRadians Angle in radians.
     * @return {number} Angle in degrees.
     */
    ol.math.toDegrees = function(angleInRadians) {
      return angleInRadians * 180 / Math.PI;
    };

    /**
     * Converts degrees to radians.
     *
     * @param {number} angleInDegrees Angle in degrees.
     * @return {number} Angle in radians.
     */
    ol.math.toRadians = function(angleInDegrees) {
      return angleInDegrees * Math.PI / 180;
    };