use crate::CoordFloat;
use crate::Destination;
use crate::Euclidean;
use crate::Point;
use num_traits::FromPrimitive;
impl<F: CoordFloat + FromPrimitive> Destination<F> for Euclidean {
fn destination(&self, origin: Point<F>, bearing: F, distance: F) -> Point<F> {
let dy = distance * bearing.to_radians().cos();
let dx = distance * bearing.to_radians().sin();
Point::new(origin.x() + dx, origin.y() + dy)
}
}
#[cfg(test)]
mod tests {
use crate::algorithm::Bearing;
use crate::algorithm::Destination;
use crate::algorithm::Distance;
use crate::{Euclidean, Point};
#[test]
fn test_360_bearing() {
let origin = Point::new(0.0, 0.0);
let distance = 1.0;
for bearing in 0..360 {
let bearing = bearing as f64;
let destination = Euclidean.destination(origin, bearing, distance);
assert_relative_eq!(
Euclidean.bearing(origin, destination),
bearing,
epsilon = 1.0e-6
);
assert_relative_eq!(
Euclidean.distance(origin, destination),
distance,
epsilon = 1.0e-6
);
}
}
}