summaryrefslogtreecommitdiffstats
path: root/src/solar_system.rs
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2026-05-05 09:12:50 -0400
committerJon Santmyer <jon@jonsantmyer.com>2026-05-05 09:12:50 -0400
commitbe2cf936ca48f3d638c3ef01f4e338dfc904c5e3 (patch)
tree9fbdbfbf3e0d427f3a6c4bd4c74901e421ef0ad6 /src/solar_system.rs
parentb35d6cf47ed154697fb45e10586206295148eb35 (diff)
downloadsystemic4x-be2cf936ca48f3d638c3ef01f4e338dfc904c5e3.tar.gz
systemic4x-be2cf936ca48f3d638c3ef01f4e338dfc904c5e3.tar.bz2
systemic4x-be2cf936ca48f3d638c3ef01f4e338dfc904c5e3.zip
seperate orbit logic from body
Diffstat (limited to 'src/solar_system.rs')
-rw-r--r--src/solar_system.rs95
1 files changed, 70 insertions, 25 deletions
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<BodyId>,
@@ -32,7 +35,12 @@ pub struct SerialOrbitalBody
pub struct OrbitalBody
{
- body: SerialOrbitalBody,
+ name: String,
+ mass: Kilograms,
+ radius: Kilometers,
+ sgp: f64,
+
+ orbit: Option<StaticOrbit>,
position: Option<cgmath::Vector3<Kilometers>>
}
@@ -64,12 +72,12 @@ impl SolarSystem
let mut bodies = Vec::<OrbitalBody>::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<Kilometers>
{
- 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<f64> { self.position.unwrap() }
- pub fn does_orbit(&self) -> bool { self.body.orbits.is_some() }
- pub fn get_orbits(&self) -> Option<BodyId> { 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<BodyId> {
+ 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<f64>
{
- 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::<f64>::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);