From be2cf936ca48f3d638c3ef01f4e338dfc904c5e3 Mon Sep 17 00:00:00 2001 From: Jon Santmyer Date: Tue, 5 May 2026 09:12:50 -0400 Subject: seperate orbit logic from body --- src/solar_system.rs | 95 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 70 insertions(+), 25 deletions(-) (limited to 'src/solar_system.rs') diff --git a/src/solar_system.rs b/src/solar_system.rs index f4ca9ae..c53f045 100644 --- a/src/solar_system.rs +++ b/src/solar_system.rs @@ -1,5 +1,8 @@ +pub mod orbit; +pub mod ship; + use serde::{Deserialize}; -use crate::{known_stars::*, timeman::Second}; +use crate::{known_stars::*, solar_system::orbit::StaticOrbit, timeman::Second}; use std::error::Error; const GRAVITATIONAL_CONSTANT: f64 = 6.67408e-20; @@ -13,7 +16,7 @@ pub type BodyId = usize; pub type SystemId = usize; #[derive(Debug, Deserialize)] -pub struct SerialOrbitalBody +pub struct CSVOrbitalBody { name: String, orbits: Option, @@ -32,7 +35,12 @@ pub struct SerialOrbitalBody pub struct OrbitalBody { - body: SerialOrbitalBody, + name: String, + mass: Kilograms, + radius: Kilometers, + sgp: f64, + + orbit: Option, position: Option> } @@ -64,12 +72,12 @@ impl SolarSystem let mut bodies = Vec::::new(); for result in body_reader.deserialize() { - let mut record: SerialOrbitalBody = result?; + let mut record: CSVOrbitalBody = result?; match record.orbits { Some(orbits) => { if record.sgp == 0.0 { - record.sgp = (bodies[orbits].body.mass + record.mass) * GRAVITATIONAL_CONSTANT; + record.sgp = (bodies[orbits].mass + record.mass) * GRAVITATIONAL_CONSTANT; } } None => {} @@ -78,7 +86,19 @@ impl SolarSystem println!("New body: {:?}", record); bodies.push(OrbitalBody { - body: record, + name: record.name, + mass: record.mass, + radius: record.radius, + sgp: record.sgp, + orbit: Some(StaticOrbit { + parent: record.orbits, + eccentricity: record.eccentricity, + inclination: record.inclination, + long_asc_node: record.long_asc_node, + long_periapsis: record.long_periapsis, + mean_long: record.mean_long, + semi_major_axis: record.semi_major_axis + }), position: None }); } @@ -116,11 +136,16 @@ impl SolarSystem body: &OrbitalBody) -> cgmath::Vector3 { - match body.body.orbits { - Some(parent) => { - let body_pos = body.position(); - let parent_pos = self.bodies[parent].position(); - body_pos + parent_pos + match &body.orbit { + Some(orbit) => { + match orbit.parent { + Some(parent) => { + let this_pos = body.position(); + let parent_pos = self.bodies[parent].position(); + this_pos + parent_pos + }, + None => body.position() + } }, None => body.position() } @@ -138,33 +163,53 @@ impl SolarSystem impl OrbitalBody { - pub fn name(&self) -> &String { &self.body.name } - pub fn radius(&self) -> f32 { self.body.radius as f32 } + pub fn name(&self) -> &String { &self.name } + pub fn radius(&self) -> f32 { self.radius as f32 } pub fn position(&self) -> cgmath::Vector3 { self.position.unwrap() } - pub fn does_orbit(&self) -> bool { self.body.orbits.is_some() } - pub fn get_orbits(&self) -> Option { self.body.orbits } + pub fn does_orbit(&self) -> bool { + match &self.orbit { + Some(orbit) => orbit.parent.is_some(), + None => false + } + } + pub fn get_orbits(&self) -> Option { + match &self.orbit { + Some(orbit) => orbit.parent(), + None => None + } + } pub fn orbital_period(&self) -> Second - { ((self.body.semi_major_axis.powf(3.0) / self.body.sgp).sqrt() * std::f64::consts::TAU) as u64 } + { + match &self.orbit { + Some(v) => v.period(self), + None => return 0 + } + } pub fn calculate_orbit_at( &self, time: Second) -> cgmath::Vector3 { - if self.body.orbits.is_none() { + let orbit = match &self.orbit { + Some(v) => v, + None => return cgmath::vec3(0.0, 0.0, 0.0) + }; + + if orbit.parent.is_none() { return cgmath::Vector3::::new(0.0, 0.0, 0.0); } - let eccentricity = self.body.eccentricity; + let eccentricity = orbit.eccentricity; - let long_asc_node = self.body.long_asc_node; - let arg_periaps = self.body.long_periapsis - long_asc_node; + let long_asc_node = orbit.long_asc_node; + let arg_periaps = orbit.long_periapsis - long_asc_node; - let sma_cubed = self.body.semi_major_axis.powf(3.0); - let mean_motion = (self.body.sgp / sma_cubed).sqrt(); + let sma_cubed = orbit.semi_major_axis.powf(3.0); + let mean_motion = (self.sgp / sma_cubed).sqrt(); - let mean_anomaly_epoch = self.body.mean_long - self.body.long_periapsis; + let mean_anomaly_epoch = orbit.mean_long - orbit.long_periapsis; let mean_anomaly = mean_anomaly_epoch + (mean_motion * time as f64); //Find the eccentric anomaly via newton's method @@ -192,9 +237,9 @@ impl OrbitalBody let vw = true_anomaly + arg_periaps; let (vw_sin, vw_cos) = vw.sin_cos(); let (omega_sin, omega_cos) = long_asc_node.sin_cos(); - let (i_sin, i_cos) = self.body.inclination.sin_cos(); + let (i_sin, i_cos) = orbit.inclination.sin_cos(); - let r = self.body.semi_major_axis * (1.0 - eccentricity * eccentric_anomaly.cos()); + let r = orbit.semi_major_axis * (1.0 - eccentricity * eccentric_anomaly.cos()); let x = r * (omega_cos * vw_cos - omega_sin * vw_sin * i_cos); let y = r * i_sin * vw_sin; let z = r * (omega_sin * vw_cos + omega_cos * vw_sin * i_cos); -- cgit v1.2.3