use numkong::HaversinesPackedMatrix;use numkong::SqEuclideans3D;use numkong::VincentysPackedMatrix;8.0.0-rc.1 · b1f866ab
Inputs are latitudes and longitudes in radians.
Outputs are meters.
HaversinesPackedMatrix and VincentysPackedMatrix pack a set of points once each.
Their methods score every point of one set, the rows, against every point of another, the columns, into a caller’s row-major slice of rows × columns entries.
use numkong::{HaversinesPackedMatrix, VincentysPackedMatrix};// Statue of Liberty (40.6892°N, 74.0445°W) → Big Ben (51.5007°N, 0.1246°W)let liberty_latitudes = [0.7101605100_f64];let liberty_longitudes = [-1.2923203180_f64];let big_ben_latitudes = [0.8988567821_f64];let big_ben_longitudes = [-0.0021746802_f64];let mut distance = [0.0_f64; 1];let liberty = VincentysPackedMatrix::new(&liberty_latitudes, &liberty_longitudes).unwrap();let big_ben = VincentysPackedMatrix::new(&big_ben_latitudes, &big_ben_longitudes).unwrap();liberty.vincentys(&big_ben, &mut distance).unwrap(); // ≈ 5,589,857 m (ellipsoidal, baseline)let liberty = HaversinesPackedMatrix::new(&liberty_latitudes, &liberty_longitudes).unwrap();let big_ben = HaversinesPackedMatrix::new(&big_ben_latitudes, &big_ben_longitudes).unwrap();liberty.haversines(&big_ben, &mut distance).unwrap(); // ≈ 5,574,848 m (spherical, ~15 km less)
Haversine uses the IUGG mean radius of 6,371,008.8 m, and Vincenty the WGS-84 ellipsoid. SqEuclideans3D scores [x, y, z] points the same way, with no packing. i32 coordinates, like Earth-fixed centimeters, give exact u64 squares, and f64 ones give f64.
StructHaversinesPackedMatrixPoints packed once as unit vectors on the mean sphere, scored with great-circle distances as rows against the columns of another pack.6
The distance is 2R × atan2(‖a − b‖, ‖a + b‖) over unit vectors a and b, which stays
conditioned at every separation, from a millimeter to the antipode, with R the mean radius.
Implements
Debug, Send, Sync
new_inPacks the points at latitudes and longitudes, in radians, using a custom allocator.
i32 coordinates yield exact u64 squares whenever every axis difference fits 32 bits, which
Earth-fixed centimeters below 4,359 km of altitude always satisfy. f64 coordinates sum their
three squares in Dot2.
Returns Err if results does not hold rows × columns entries.
StructVincentysPackedMatrixPoints packed once as longitudes and the sines and cosines of their reduced latitudes, scored with Vincenty geodesic distances on the WGS-84 ellipsoid as rows against the columns of another pack.3
Uses Vincenty's iterative formula for oblate spheroid geodesics:
Reduced latitudes: tan(U) = (1−f) × tan(φ)
Iterate until convergence: λ → L + (1−C) × f × sin(α) × [σ + C × sin(σ) × ...]
Compute: u² = cos²(α) × (a² − b²)/b²
Series coefficients A, B from u²
Distance: s = b × A × (σ − Δσ)
Where a = equatorial radius, b = polar radius, f = flattening. ~20× more accurate than Haversine
for long distances. Inputs are in radians, outputs in meters. A pair still unsettled after the
iteration limit, which happens only near the antipode, reports its last iterate.
Implements
Debug, Send, Sync
new_inPacks the points at latitudes and longitudes, in radians, using a custom allocator.