const deg2rad = 0.01745329251994328; /*! * @brief Get the projected point ahead by a distance bases on current location and heading * @param x x UTM * @param y y UTM * @param distance in meters * @param heading in degrees * @return projected coordinate in an array as [x,y] */ function projectedPointAheadByDistance(x, y, distance, heading) { let projectedX = 0, projectedY = 0; const radHeading = heading * deg2rad; projectedX = x + distance * Math.sin(radHeading); projectedY = y + distance * Math.cos(radHeading); return [projectedX, projectedY]; }; /** * @brief Get the projected point ahead by number of seconds bases on current location, speed and heading * @param x x UTM * @param y y UTM * @param speed in meters per second * @param heading in degrees * @param aheadSecs in seconds * @return projected coordinate in an array as [x,y] */ function projectedPointAheadByTime(x, y, speed, heading, aheadSecs) { return projectedPointAheadByDistance(x, y, speed * aheadSecs, heading); }; /** * An optimized version of Bubble Sort * @param {*} arr the array to sort */ function bubbleSort(arr) { if (!arr || !arr.length) return; let n = arr.length, n2, v; do { n2 = 0; for (let k = 1; k < n; k++) { if (arr[k - 1].y > arr[k].y) { v = arr[k - 1]; arr[k - 1] = arr[k]; arr[k] = v; n2 = k; } } n = n2; } while (n2 != 0); } function segmentLengthP(a, b) { return segmentLength(a.x, a.y, b.x, b.y); } function segmentLength(x1, y1, x2, y2) { return Math.hypot(x1 - x2, y1 - y2); } module.exports = { projectedPointAheadByDistance, projectedPointAheadByTime, bubbleSort, segmentLengthP, segmentLength }