Skip to main content

geometry_strategy/geographic/
direct.rs

1//! Shared result shape for direct geodesic formulas.
2//!
3//! Mirrors `boost::geometry::formula::result_direct<CT>` from
4//! `formulas/result_direct.hpp:24-47`.
5
6use geometry_cs::Spheroid;
7
8/// Coordinates and reverse azimuth produced by a direct geodesic solution.
9///
10/// All angular values are radians. Mirrors `formula::result_direct` from
11/// `formulas/result_direct.hpp:29-42`.
12#[derive(Debug, Clone, Copy, PartialEq)]
13pub struct DirectResult {
14    /// Destination longitude in normalized radians, `[-π, π]`.
15    pub lon2: f64,
16    /// Destination latitude in radians.
17    pub lat2: f64,
18    /// Final/reverse azimuth in radians.
19    pub reverse_azimuth: f64,
20    /// Reduced geodesic length in the spheroid's radius unit.
21    pub reduced_length: f64,
22    /// Dimensionless forward geodesic scale.
23    pub geodesic_scale: f64,
24}
25
26impl Default for DirectResult {
27    fn default() -> Self {
28        Self {
29            lon2: 0.0,
30            lat2: 0.0,
31            reverse_azimuth: 0.0,
32            reduced_length: 0.0,
33            geodesic_scale: 1.0,
34        }
35    }
36}
37
38impl DirectResult {
39    #[cfg(feature = "std")]
40    pub(crate) fn solved(
41        longitude1: f64,
42        latitude1: f64,
43        azimuth1: f64,
44        spheroid: Spheroid,
45        lon2: f64,
46        lat2: f64,
47        reverse_azimuth: f64,
48    ) -> Self {
49        let quantities = super::differential::differential_quantities(
50            longitude1,
51            latitude1,
52            lon2,
53            lat2,
54            azimuth1,
55            reverse_azimuth,
56            spheroid,
57        );
58        Self {
59            lon2,
60            lat2,
61            reverse_azimuth,
62            reduced_length: quantities.reduced_length,
63            geodesic_scale: quantities.geodesic_scale,
64        }
65    }
66}
67
68#[cfg(feature = "std")]
69pub(crate) fn normalize_longitude(mut longitude: f64) -> f64 {
70    let pi = core::f64::consts::PI;
71    let two_pi = 2.0 * pi;
72    while longitude > pi {
73        longitude -= two_pi;
74    }
75    while longitude < -pi {
76        longitude += two_pi;
77    }
78    longitude
79}