1use crate::enu::ENU;
2use crate::utils::RealFieldCopy;
3use crate::Access;
4use na::Vector3;
5use std::convert::From;
6use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
7
8#[derive(Debug, Copy, Clone, PartialEq)]
14pub struct NED<N: RealFieldCopy>(Vector3<N>);
15
16impl<N: RealFieldCopy> NED<N> {
17 pub fn new(n: N, e: N, d: N) -> NED<N> {
19 NED(Vector3::new(n, e, d))
20 }
21
22 pub fn norm(&self) -> N {
24 self.0.norm()
25 }
26}
27
28impl<N: RealFieldCopy> NED<N> {
29 pub fn north(&self) -> N {
31 self.0.x
32 }
33
34 pub fn east(&self) -> N {
36 self.0.y
37 }
38
39 pub fn down(&self) -> N {
41 self.0.z
42 }
43}
44
45impl<N: RealFieldCopy + Neg<Output = N>> From<NED<N>> for ENU<N> {
46 fn from(e: NED<N>) -> Self {
48 ENU::new(e.east(), e.north(), -e.down())
49 }
50}
51
52impl<N: RealFieldCopy + Add<N, Output = N>> Add<NED<N>> for NED<N> {
53 type Output = NED<N>;
54 fn add(self, right: NED<N>) -> NED<N> {
55 NED(self.0 + right.0)
56 }
57}
58
59impl<N: RealFieldCopy + AddAssign<N>> AddAssign<NED<N>> for NED<N> {
60 fn add_assign(&mut self, right: NED<N>) {
61 self.0 += right.0
62 }
63}
64
65impl<N: RealFieldCopy + Sub<N, Output = N>> Sub<NED<N>> for NED<N> {
66 type Output = NED<N>;
67 fn sub(self, right: NED<N>) -> NED<N> {
68 NED(self.0 - right.0)
69 }
70}
71
72impl<N: RealFieldCopy + SubAssign<N>> SubAssign<NED<N>> for NED<N> {
73 fn sub_assign(&mut self, right: NED<N>) {
74 self.0 -= right.0
75 }
76}
77
78impl<N: RealFieldCopy + Mul<N, Output = N>> Mul<N> for NED<N> {
79 type Output = NED<N>;
80 fn mul(self, right: N) -> NED<N> {
81 NED(self.0 * right)
82 }
83}
84
85impl<N: RealFieldCopy + MulAssign<N>> MulAssign<N> for NED<N> {
86 fn mul_assign(&mut self, right: N) {
87 self.0 *= right
88 }
89}
90
91impl<N: RealFieldCopy + Div<N, Output = N>> Div<N> for NED<N> {
92 type Output = NED<N>;
93 fn div(self, right: N) -> NED<N> {
94 NED(self.0 / right)
95 }
96}
97
98impl<N: RealFieldCopy + DivAssign<N>> DivAssign<N> for NED<N> {
99 fn div_assign(&mut self, right: N) {
100 self.0 /= right
101 }
102}
103
104impl<N: RealFieldCopy> Access<Vector3<N>> for NED<N> {
105 fn access(self) -> Vector3<N> {
106 self.0
107 }
108}
109
110#[cfg(test)]
111mod tests {
112 use super::*;
113 use crate::enu::ENU;
114
115 quickcheck! {
116 fn create_ned(n: f32, e: f32, d: f32) -> () {
117 NED::new(n, e, d);
118 }
119
120 fn get_components(n: f32, e: f32, d: f32) -> () {
121 let vec = NED::new(n, e, d);
122 assert_eq!(vec.north(), n);
123 assert_eq!(vec.east(), e);
124 assert_eq!(vec.down(), d);
125 }
126
127 fn into_enu(n: f32, e: f32, d: f32) -> () {
128 let ned = NED::new(n, e, d);
129 let enu: ENU<_> = ned.into();
130 assert_eq!(n, enu.north());
131 assert_eq!(e, enu.east());
132 assert_eq!(d, -enu.up());
133 }
134
135 fn add_enu(n: f32, e: f32, d: f32) -> () {
136 let ned = NED::new(n, e, d);
137 let enu = ENU::new(e, n, -d);
138 let sum = enu + ned;
139 let twi = ned * 2.0;
140 assert_eq!(sum.north(), twi.north());
141 assert_eq!(sum.east(), twi.east());
142 assert_eq!(sum.up(), -twi.down());
143 }
144 }
145}