wxbox/client/src/lib/vincenty.ts
core 32244daafe
Some checks are pending
Verify Latest Dependencies / Verify Latest Dependencies (push) Waiting to run
build and test / wxbox - latest (push) Waiting to run
mostly functional v2 rendering
2025-05-30 23:38:29 -04:00

48 lines
No EOL
2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const a = 6378137.0;
const b = 6356752.314245;
const f = (a-b) / a;
export function degToRad(deg: number): number {
return deg * (Math.PI / 180);
}
export function radToDeg(radian: number): number {
return radian * (180 / Math.PI);
}
export function forwardGeodesic(α1: number, φ1: number, λ1: number, s: number): [number, number, number] {
const sinα1 = Math.sin(α1);
const cosα1 = Math.cos(α1);
const tanU1 = (1-f) * Math.tan(φ1), cosU1 = 1 / Math.sqrt((1 + tanU1*tanU1)), sinU1 = tanU1 * cosU1;
const σ1 = Math.atan2(tanU1, cosα1); // σ1 = angular distance on the sphere from the equator to P1
const sinα = cosU1 * sinα1; // α = azimuth of the geodesic at the equator
const cosSqα = 1 - sinα*sinα;
const uSq = cosSqα * (a*a - b*b) / (b*b);
const A = 1 + uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)));
const B = uSq/1024 * (256+uSq*(-128+uSq*(74-47*uSq)));
let σ = s / (b*A), sinσ = null, cosσ = null; // σ = angular distance P₁ P₂ on the sphere
let cos2σ = null; // σₘ = angular distance on the sphere from the equator to the midpoint of the line
let σʹ = null;
do {
cos2σ = Math.cos(2*σ1 + σ);
sinσ = Math.sin(σ);
cosσ = Math.cos(σ);
const Δσ = B*sinσ*(cos2σ+B/4*(cosσ*(-1+2*cos2σ*cos2σ)-B/6*cos2σ*(-3+4*sinσ*sinσ)*(-3+4*cos2σ*cos2σ)));
σʹ = σ;
σ = s / (b*A) + Δσ;
} while (Math.abs(σ-σʹ) > 1e-12);
const x = sinU1*sinσ - cosU1*cosσ*cosα1;
const φ2 = Math.atan2(sinU1*cosσ + cosU1*sinσ*cosα1, (1-f)*Math.sqrt(sinα*sinα + x*x));
const λ = Math.atan2(sinσ*sinα1, cosU1*cosσ - sinU1*sinσ*cosα1);
const C = f/16*cosSqα*(4+f*(4-3*cosSqα));
const L = λ - (1-C) * f * sinα * (σ + C*sinσ*(cos2σ+C*cosσ*(-1+2*cos2σ*cos2σ)));
const λ2 = λ1 + L;
const α2 = Math.atan2(sinα, -x); // final bearing
return [φ2, λ2, α2];
}