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