summaryrefslogtreecommitdiffstats
path: root/src/solar_system
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2026-05-06 12:01:42 -0400
committerJon Santmyer <jon@jonsantmyer.com>2026-05-06 12:01:42 -0400
commit9788d9037ad7199701b1710c28559cb96bce5aec (patch)
treec490b40b1f0057c98c2b4bb3c2593f915313d14f /src/solar_system
parentd67fca88b17120566a93004c99dadeef0a61964b (diff)
downloadsystemic4x-9788d9037ad7199701b1710c28559cb96bce5aec.tar.gz
systemic4x-9788d9037ad7199701b1710c28559cb96bce5aec.tar.bz2
systemic4x-9788d9037ad7199701b1710c28559cb96bce5aec.zip
regenerate orbit lines based on system tick interval
Diffstat (limited to 'src/solar_system')
-rw-r--r--src/solar_system/body.rs96
-rw-r--r--src/solar_system/orbit.rs64
-rw-r--r--src/solar_system/ship.rs34
3 files changed, 177 insertions, 17 deletions
diff --git a/src/solar_system/body.rs b/src/solar_system/body.rs
new file mode 100644
index 0000000..55d3d4a
--- /dev/null
+++ b/src/solar_system/body.rs
@@ -0,0 +1,96 @@
+use super::*;
+
+pub type BodyId = usize;
+
+pub struct OrbitalBody
+{
+ id: BodyId,
+ name: String,
+ mass: Kilograms,
+ radius: Kilometers,
+ sgp: f64,
+
+ orbit: Option<StaticOrbit>,
+ rel_pos: Option<cgmath::Vector3<Kilometers>>
+}
+
+impl OrbitalBody
+{
+ pub fn new_from_record(
+ id: BodyId,
+ record: CSVOrbitalBody)
+ -> Self {
+ Self {
+ id: id,
+ name: record.name,
+ mass: record.mass,
+ radius: record.radius,
+ sgp: record.sgp,
+ orbit: match record.orbits {
+ Some(parent) => Some(StaticOrbit::new(
+ parent,
+ record.eccentricity,
+ record.inclination,
+ record.long_asc_node,
+ record.long_periapsis,
+ record.mean_long,
+ record.semi_major_axis
+ )),
+ None => None
+ },
+ rel_pos: None
+ }
+ }
+
+ pub fn id(&self) -> BodyId { self.id }
+ pub fn name(&self) -> &String { &self.name }
+ pub fn radius(&self) -> f32 { self.radius as f32 }
+ pub fn relative_position(&self) -> cgmath::Vector3<f64> { self.rel_pos.unwrap() }
+ pub fn mass(&self) -> Kilograms { self.mass }
+ pub fn sgp(&self) -> f64 { self.sgp }
+
+ pub fn absolute_position(
+ &self,
+ solar_system: &SolarSystem)
+ -> cgmath::Vector3<Kilometers>
+ {
+ match &self.orbit {
+ Some(orbit) => {
+ let parent_pos = solar_system.bodies()[orbit.parent()].absolute_position(solar_system);
+ parent_pos + self.relative_position()
+ },
+ None => self.relative_position()
+ }
+ }
+
+ pub fn get_orbit(&self) -> &Option<StaticOrbit> { &self.orbit }
+
+ pub fn orbital_period(
+ &self
+ ) -> Second
+ {
+ match &self.orbit {
+ Some(v) => v.period(self),
+ None => return 0
+ }
+ }
+
+ pub fn calculate_orbit_at(
+ &self,
+ time: Second)
+ -> cgmath::Vector3<Kilometers>
+ {
+ match &self.orbit {
+ Some(orbit) => orbit.calculate_position_at(self, time),
+ None => cgmath::vec3(0.0, 0.0, 0.0)
+ }
+ }
+
+ pub fn update(
+ &mut self,
+ time: Second)
+ {
+ self.rel_pos = Some(self.calculate_orbit_at(time));
+ }
+}
+
diff --git a/src/solar_system/orbit.rs b/src/solar_system/orbit.rs
index b042bd3..461de7b 100644
--- a/src/solar_system/orbit.rs
+++ b/src/solar_system/orbit.rs
@@ -1,29 +1,65 @@
-use crate::solar_system::{Angle, BodyId, Kilometers, OrbitalBody, Percentage};
+use crate::solar_system::{Angle, BodyId, Kilometers, OrbitalBody, Percentage, SolarSystem};
use crate::timeman::{Second};
pub struct StaticOrbit
{
- pub parent: Option<BodyId>,
- pub eccentricity: Percentage,
- pub inclination: Angle,
- pub long_asc_node: Angle,
- pub long_periapsis: Angle,
- pub mean_long: Angle,
-
- pub semi_major_axis: Kilometers,
+ parent: BodyId,
+ eccentricity: Percentage,
+ inclination: Angle,
+ long_asc_node: Angle,
+ long_periapsis: Angle,
+ mean_long: Angle,
+
+ semi_major_axis: Kilometers,
}
impl StaticOrbit
{
+ pub fn new(
+ parent: BodyId,
+ eccentricity: Percentage,
+ inclination: Angle,
+ long_asc_node: Angle,
+ long_periapsis: Angle,
+ mean_long: Angle,
+ semi_major_axis: Kilometers)
+ -> Self {
+ Self {
+ parent,
+ eccentricity,
+ inclination,
+ long_asc_node,
+ long_periapsis,
+ mean_long,
+ semi_major_axis
+ }
+ }
+
+ pub fn new_circular(
+ parent: &OrbitalBody,
+ radius: Kilometers)
+ -> Self
+ {
+ Self {
+ parent: parent.id(),
+ eccentricity: 1e-6,
+ inclination: 0.0,
+ long_asc_node: 0.0,
+ long_periapsis: 0.0,
+ mean_long: 0.0,
+ semi_major_axis: radius
+ }
+ }
+
pub fn period(
&self,
this_body: &OrbitalBody)
-> Second
{
- ((self.semi_major_axis.powf(3.0) / this_body.sgp).sqrt() * std::f64::consts::TAU) as Second
+ ((self.semi_major_axis.powf(3.0) / this_body.sgp()).sqrt() * std::f64::consts::TAU) as Second
}
- pub fn parent(&self) -> Option<BodyId> {
+ pub fn parent(&self) -> BodyId {
self.parent
}
@@ -33,17 +69,13 @@ impl StaticOrbit
time: Second)
-> cgmath::Vector3<f64>
{
- if self.parent.is_none() {
- return cgmath::Vector3::<f64>::new(0.0, 0.0, 0.0);
- }
-
let eccentricity = self.eccentricity;
let long_asc_node = self.long_asc_node;
let arg_periaps = self.long_periapsis - long_asc_node;
let sma_cubed = self.semi_major_axis.powf(3.0);
- let mean_motion = (this_body.sgp / sma_cubed).sqrt();
+ let mean_motion = (this_body.sgp() / sma_cubed).sqrt();
let mean_anomaly_epoch = self.mean_long - self.long_periapsis;
let mean_anomaly = mean_anomaly_epoch + (mean_motion * time as f64);
diff --git a/src/solar_system/ship.rs b/src/solar_system/ship.rs
index eb4cdf3..57c0184 100644
--- a/src/solar_system/ship.rs
+++ b/src/solar_system/ship.rs
@@ -1,4 +1,36 @@
+use crate::solar_system::{Kilograms, Kilometers, SolarSystem, body::BodyId, orbit::StaticOrbit};
+
+pub type ShipId = usize;
+
pub struct Ship
{
-
+ name: String,
+ mass: Kilograms,
+
+ position: cgmath::Vector3<Kilometers>,
+ velocity: cgmath::Vector3<f32>,
+ acceleration: cgmath::Vector3<f32>,
+
+ baked_orbit: Option<StaticOrbit>
+}
+
+impl Ship
+{
+ pub fn new(
+ name: String,
+ mass: Kilograms,
+ system: &SolarSystem,
+ orbiting: BodyId,
+ orbit_sma: Kilometers)
+ -> Self
+ {
+ Self {
+ name,
+ mass,
+ position: cgmath::vec3(0.0, 0.0, 0.0),
+ velocity: cgmath::vec3(0.0, 0.0, 0.0),
+ acceleration: cgmath::vec3(0.0, 0.0, 0.0),
+ baked_orbit: None
+ }
+ }
}