summaryrefslogtreecommitdiffstats
path: root/src/orbital.rs
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2024-09-30 12:01:07 -0400
committerJon Santmyer <jon@jonsantmyer.com>2024-09-30 12:01:07 -0400
commit63bd19127f66dda81007fcd0d8857e978740101f (patch)
tree781e971abde6f79b35b457927129066df42d955e /src/orbital.rs
downloadsystemic-master.tar.gz
systemic-master.tar.bz2
systemic-master.zip
First commitHEADmaster
Diffstat (limited to 'src/orbital.rs')
-rw-r--r--src/orbital.rs164
1 files changed, 164 insertions, 0 deletions
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<usize>,
+
+ //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<usize>,
+ 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<usize> { 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
+ }
+ }
+}