atm_refraction/
ray_state.rs

1use crate::Environment;
2use na::{State, StateDerivative};
3use std::ops::{Add, Div, Mul, Neg, Sub};
4
5#[derive(Clone, Copy, Debug)]
6pub struct RayState {
7    pub x: f64,
8    pub h: f64,
9    pub dh: f64,
10}
11
12impl RayState {
13    pub fn get_angle(&self, env: &Environment) -> f64 {
14        if let Some(r) = env.radius() {
15            (self.dh * r / (self.h + r)).atan()
16        } else {
17            self.dh.atan()
18        }
19    }
20}
21
22#[derive(Clone, Copy, Debug)]
23pub struct RayStateDerivative {
24    pub dx: f64,
25    pub dh: f64,
26    pub d2h: f64,
27}
28
29impl Add<RayStateDerivative> for RayStateDerivative {
30    type Output = RayStateDerivative;
31    fn add(self, other: RayStateDerivative) -> RayStateDerivative {
32        RayStateDerivative {
33            dx: self.dx + other.dx,
34            dh: self.dh + other.dh,
35            d2h: self.d2h + other.d2h,
36        }
37    }
38}
39
40impl Sub<RayStateDerivative> for RayStateDerivative {
41    type Output = RayStateDerivative;
42    fn sub(self, other: RayStateDerivative) -> RayStateDerivative {
43        RayStateDerivative {
44            dx: self.dx - other.dx,
45            dh: self.dh - other.dh,
46            d2h: self.d2h - other.d2h,
47        }
48    }
49}
50
51impl Mul<f64> for RayStateDerivative {
52    type Output = RayStateDerivative;
53    fn mul(self, other: f64) -> RayStateDerivative {
54        RayStateDerivative {
55            dx: self.dx * other,
56            dh: self.dh * other,
57            d2h: self.d2h * other,
58        }
59    }
60}
61
62impl Div<f64> for RayStateDerivative {
63    type Output = RayStateDerivative;
64    fn div(self, other: f64) -> RayStateDerivative {
65        RayStateDerivative {
66            dx: self.dx / other,
67            dh: self.dh / other,
68            d2h: self.d2h / other,
69        }
70    }
71}
72
73impl Neg for RayStateDerivative {
74    type Output = RayStateDerivative;
75    fn neg(self) -> RayStateDerivative {
76        RayStateDerivative {
77            dx: -self.dx,
78            dh: -self.dh,
79            d2h: -self.d2h,
80        }
81    }
82}
83
84impl StateDerivative for RayStateDerivative {
85    fn abs(&self) -> f64 {
86        (self.dx * self.dx + self.dh * self.dh + self.d2h * self.d2h).sqrt()
87    }
88}
89
90impl State for RayState {
91    type Derivative = RayStateDerivative;
92    fn shift_in_place(&mut self, dir: &RayStateDerivative, amount: f64) {
93        self.x += dir.dx * amount;
94        self.h += dir.dh * amount;
95        self.dh += dir.d2h * amount;
96    }
97}