gistools/geometry/tools/points/
destination.rs1use crate::space::EARTH_RADIUS;
2use libm::{asin, atan2, cos, sin};
3use s2json::{GetXY, NewXY};
4
5pub fn destination<P: GetXY, Q: NewXY>(
15 start: &P,
16 bearing: f64,
17 distance: f64,
18 radius: Option<f64>,
19) -> Q {
20 let s_lon = start.x().to_radians();
21 let s_lat = start.y().to_radians();
22 let bearing = bearing.to_radians();
23 let radius = radius.unwrap_or(EARTH_RADIUS);
24 let radians = distance / radius;
25
26 let e_lat = asin(sin(s_lat) * cos(radians) + cos(s_lat) * sin(radians) * cos(bearing));
27 let e_lon = s_lon
28 + atan2(sin(bearing) * sin(radians) * cos(s_lat), cos(radians) - sin(s_lat) * sin(e_lat));
29
30 Q::new_xy(e_lon.to_degrees(), e_lat.to_degrees())
31}