use crate::CoordFloat;
use crate::Euclidean;
use crate::Point;
use crate::algorithm::Bearing;
use num_traits::FromPrimitive;
impl<F: CoordFloat + FromPrimitive> Bearing<F> for Euclidean {
fn bearing(&self, origin: Point<F>, destination: Point<F>) -> F {
let three_sixty =
F::from(360.0).expect("Numeric type to be constructable from primitive 360");
let dx = destination.x() - origin.x();
let dy = destination.y() - origin.y();
let angle = dx.atan2(dy);
let mut bearing = angle.to_degrees();
bearing = (bearing + three_sixty) % three_sixty;
bearing
}
}
#[cfg(test)]
mod tests {
use crate::algorithm::Bearing;
use crate::{Euclidean, Point};
#[test]
fn test_bearing() {
let origin = Point::new(10.0, 10.0);
let north = Point::new(10.0, 11.0);
let south = Point::new(10.0, 9.0);
let east = Point::new(11.0, 10.0);
let west = Point::new(9.0, 10.0);
let bearing = Euclidean.bearing(origin, north);
assert_eq!(bearing, 0.0);
let bearing = Euclidean.bearing(origin, south);
assert_eq!(bearing, 180.0);
let bearing = Euclidean.bearing(origin, east);
assert_eq!(bearing, 90.0);
let bearing = Euclidean.bearing(origin, west);
assert_eq!(bearing, 270.0);
}
#[test]
fn test_self_bearing() {
let origin = Point::new(0.0, 0.0);
let bearing = Euclidean.bearing(origin, origin);
assert_eq!(bearing, 0.0);
}
}