From 63bd19127f66dda81007fcd0d8857e978740101f Mon Sep 17 00:00:00 2001 From: Jon Santmyer Date: Mon, 30 Sep 2024 12:01:07 -0400 Subject: First commit --- src/orbital.rs | 164 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 src/orbital.rs (limited to 'src/orbital.rs') diff --git a/src/orbital.rs b/src/orbital.rs new file mode 100644 index 0000000..178273a --- /dev/null +++ b/src/orbital.rs @@ -0,0 +1,164 @@ +use super::units::*; +use super::system::System; +use std::vec::Vec; +use std::rc::Rc; +use std::cell::RefCell; + +pub struct Orbital +{ + origin : Option, + + //Euler angles for a given time (T) relative to origin + rel_pos : Option<(Second, Meter, Rad, Rad, Rad)>, + //Position for a given time (T) in absolute system coordinates + abs_pos : Option<(Second, Meter, Meter, Meter)>, + + name : String, + + //Physical parameters + mass : Kilogram, + radius : Meter, + + //Orbital parameters + semi_major_axis : Meter, + eccentricity : f64, + inclination : Rad, + longitude_asc_node : Rad, + argument_periapsis : Rad, + mean_anomaly_epoch : Rad, +} + +pub struct OrbitalBuilder +{ + origin : Option, + name : String, + mass : Kilogram, + radius : Meter, + semi_major_axis : Meter, + eccentricity : f64, + inclination : Rad, + longitude_asc_node : Rad, + argument_periapsis : Rad, + mean_anomaly_epoch : Rad, +} + +impl Orbital +{ + pub fn tick(&mut self, + origin : &mut Orbital, + t : Second) + { + match self.rel_pos { + None => {}, + Some(rel_pos) => { + if rel_pos.0 == t { return; } + } + } + + let origin_mass = origin.mass; + + let std_grav_param = GRAVITATIONAL_CONSTANT * (origin_mass + self.mass); + let mean_angular_motion = f64::sqrt(std_grav_param / self.semi_major_axis.powi(3)); + let mean_anomaly = self.mean_anomaly_epoch + (mean_angular_motion * t as f64); + + let mut eccentric_anomaly = mean_anomaly; + loop { + let de = (eccentric_anomaly - + self.eccentricity * eccentric_anomaly.sin() - + mean_anomaly) / + (1.0 - self.eccentricity * eccentric_anomaly.cos()); + eccentric_anomaly -= de; + if de.abs() < 1e6 { break; } + } + + //True anomaly + let beta = self.eccentricity / + (1.0 + f64::sqrt(1.0 - self.eccentricity.powi(2))); + let true_anomaly = eccentric_anomaly * 2.0 * + f64::atan((beta * eccentric_anomaly.sin()) / + (1.0 - beta * eccentric_anomaly.cos())); + + let distance = self.semi_major_axis * + (1.0 - self.eccentricity * eccentric_anomaly.cos()); + + self.rel_pos = Some((t, distance, self.longitude_asc_node, self.inclination, true_anomaly)); + println!("{0:?}", self.rel_pos.unwrap()); + } + + pub fn pos(&mut self, + system : &System, + t : Second) + -> (Meter, Meter, Meter) + { + (0.0, 0.0, 0.0) + } + + pub fn name(&self) -> &String { &self.name } + + pub fn origin(&self) -> Option { self.origin } +} + +impl OrbitalBuilder +{ + pub fn new() -> OrbitalBuilder { + OrbitalBuilder { + origin : None, + name : "".to_string(), + mass : 0.0, + radius : 0.0, + semi_major_axis : 0.0, + eccentricity : 0.0, + inclination : 0.0, + longitude_asc_node : 0.0, + argument_periapsis : 0.0, + mean_anomaly_epoch : 0.0, + } + } + pub fn orbits(mut self, parent : usize) -> OrbitalBuilder + { self.origin = Some(parent); self } + + pub fn name(mut self, name : String) -> OrbitalBuilder + { self.name = name; self } + + pub fn mass(mut self, mass : Kilogram) -> OrbitalBuilder + { self.mass = mass; self } + + pub fn radius(mut self, radius : Meter) -> OrbitalBuilder + { self.radius = radius; self } + + pub fn semi_major_axis(mut self, sma : Meter) -> OrbitalBuilder + { self.semi_major_axis = sma; self } + + pub fn eccentricity(mut self, e : Rad) -> OrbitalBuilder + { self.eccentricity = e; self } + + pub fn inclination(mut self, i : Rad) -> OrbitalBuilder + { self.inclination = i; self } + + pub fn long_asc_node(mut self, omega : Rad) -> OrbitalBuilder + { self.longitude_asc_node = omega; self } + + pub fn argument_periapsis(mut self, w : Rad) -> OrbitalBuilder + { self.argument_periapsis = w; self } + + pub fn mean_anomaly_epoch(mut self, mean_anomaly : Rad) -> OrbitalBuilder + { self.mean_anomaly_epoch = mean_anomaly; self } + + pub fn build(self) -> Orbital + { + Orbital { + origin : self.origin, + rel_pos : None, + abs_pos : None, + name : self.name, + mass : self.mass, + radius : self.radius, + semi_major_axis : self.semi_major_axis, + eccentricity : self.eccentricity, + inclination : self.inclination, + longitude_asc_node : self.longitude_asc_node, + argument_periapsis : self.argument_periapsis, + mean_anomaly_epoch : self.mean_anomaly_epoch + } + } +} -- cgit v1.2.1