use super::*;
use crate::math::angular;
#[derive(Debug, Default, PartialEq, Copy, Clone)]
pub struct Coor2D(pub [f64; 2]);
impl CoordinateTuple for Coor2D {
fn new(fill: f64) -> Self {
Coor2D([fill; 2])
}
fn dim(&self) -> usize {
2
}
fn nth_unchecked(&self, n: usize) -> f64 {
self.0[n]
}
fn set_nth_unchecked(&mut self, n: usize, value: f64) {
self.0[n] = value;
}
}
impl Coor2D {
#[must_use]
pub fn geo(latitude: f64, longitude: f64) -> Coor2D {
Coor2D([longitude.to_radians(), latitude.to_radians()])
}
#[must_use]
pub fn arcsec(longitude: f64, latitude: f64) -> Coor2D {
Coor2D([
longitude.to_radians() / 3600.,
latitude.to_radians() / 3600.,
])
}
#[must_use]
pub fn gis(longitude: f64, latitude: f64) -> Coor2D {
Coor2D([longitude.to_radians(), latitude.to_radians()])
}
#[must_use]
pub fn raw(first: f64, second: f64) -> Coor2D {
Coor2D([first, second])
}
#[must_use]
pub fn iso_dm(latitude: f64, longitude: f64) -> Coor2D {
let longitude = angular::iso_dm_to_dd(longitude);
let latitude = angular::iso_dm_to_dd(latitude);
Coor2D::geo(latitude, longitude)
}
#[must_use]
pub fn iso_dms(latitude: f64, longitude: f64) -> Coor2D {
let longitude = angular::iso_dms_to_dd(longitude);
let latitude = angular::iso_dms_to_dd(latitude);
Coor2D::geo(latitude, longitude)
}
#[must_use]
pub fn nan() -> Coor2D {
Coor2D([f64::NAN, f64::NAN])
}
#[must_use]
pub fn origin() -> Coor2D {
Coor2D([0., 0.])
}
#[must_use]
pub fn ones() -> Coor2D {
Coor2D([1., 1.])
}
#[must_use]
pub fn scale(&self, factor: f64) -> Coor2D {
Coor2D([self.x() * factor, self.y() * factor])
}
#[must_use]
pub fn dot(&self, other: Coor2D) -> f64 {
self.x() * other.x() + self.y() * other.y()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn distances() {
let e = Ellipsoid::default();
let lat = angular::dms_to_dd(55, 30, 36.);
let lon = angular::dms_to_dd(12, 45, 36.);
let dms = Coor2D::geo(lat, lon);
let geo = Coor2D::geo(55.51, 12.76);
assert!(e.distance(&geo, &dms) < 1e-10);
}
#[test]
fn coor2d() {
let c = Coor2D::raw(12., 55.).to_radians();
let d = Coor2D::gis(12., 55.);
assert_eq!(c, d);
assert_eq!(d.x(), 12f64.to_radians());
assert_eq!(d.x().to_degrees(), c.x().to_degrees());
}
#[test]
fn array() {
let b = Coor2D::raw(7., 8.);
let c = [b.x(), b.y(), f64::NAN, f64::NAN];
assert_eq!(b.x(), c[0]);
}
#[test]
fn arithmetic() {
let a = Coor2D([1., 2.]);
let b = Coor2D([4., 3.]);
assert_eq!(a.dot(b), 10.)
}
}