signalk-tides
Version:
Tidal predictions for the vessel's position from various online sources.
28 lines (27 loc) • 1.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.approximateTideHeightAt = approximateTideHeightAt;
/** Given a list of tide extremes, estimate the height at a specific time. */
function approximateTideHeightAt(extremes, time) {
const sorted = extremes.slice().sort((a, b) => new Date(a.time).getTime() - new Date(b.time).getTime());
const prev = sorted.filter(h => new Date(h.time) <= time).at(-1);
const next = sorted.filter(h => new Date(h.time) >= time).at(0);
if (!prev)
throw new Error("Missing height data before " + time.toISOString());
if (!next)
throw new Error("Missing height data after " + time.toISOString());
const progress = (time.getTime() - new Date(prev.time).getTime()) /
(new Date(next.time).getTime() - new Date(prev.time).getTime());
const value = interpolate(prev.value, next.value, easeSine(progress));
return parseFloat(value.toFixed(3));
}
/** Interpolate between two values using the given progress (0-1). */
function interpolate(start, end, progress) {
return start + (end - start) * progress;
}
function easeSine(progress) {
// Map progress [0..1] to angle [0..π]
const angle = progress * Math.PI;
// Use sine to ease in/out
return (1 - Math.cos(angle)) / 2;
}