use sciforge::hub::domain::common::constants::{AU, EARTH_MASS, EARTH_RADIUS, G, SOLAR_MASS};
use crate::{BodyId, CelestialBody, Vec3};
pub const MU_SUN: f64 = G * SOLAR_MASS;
pub const DEFAULT_TIMESTEP_S: f64 = 3600.0;
pub const GRAVITATIONAL_SOFTENING: f64 = 1e3;
pub const J2_EARTH: f64 = 1.08263e-3;
pub const J2_JUPITER: f64 = 1.4736e-2;
pub const J2_SATURN: f64 = 1.6298e-2;
pub const J2_MARS: f64 = 1.96045e-3;
pub const J2_SUN: f64 = 2.0e-7;
pub fn default_bodies() -> Vec<CelestialBody> {
vec![
CelestialBody {
id: BodyId::Sun,
name: "Sun",
mass: SOLAR_MASS,
radius: suns::SOLAR_RADIUS,
position: Vec3::ZERO,
velocity: Vec3::ZERO,
acceleration: Vec3::ZERO,
j2: J2_SUN,
},
CelestialBody {
id: BodyId::Mercury,
name: "Mercury",
mass: mercurys::physics::orbit::MERCURY_MASS,
radius: mercurys::physics::orbit::MERCURY_RADIUS,
position: Vec3::new(0.387 * AU, 0.0, 0.0),
velocity: Vec3::new(0.0, 47_362.0, 0.0),
acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::Venus,
name: "Venus",
mass: venuss::VENUS_MASS,
radius: venuss::VENUS_RADIUS,
position: Vec3::new(0.723 * AU, 0.0, 0.0),
velocity: Vec3::new(0.0, 35_020.0, 0.0),
acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::Earth,
name: "Earth",
mass: EARTH_MASS,
radius: EARTH_RADIUS,
position: Vec3::new(AU, 0.0, 0.0),
velocity: Vec3::new(0.0, 29_784.8, 0.0),
acceleration: Vec3::ZERO,
j2: J2_EARTH,
},
CelestialBody {
id: BodyId::Mars,
name: "Mars",
mass: marss::MARS_MASS,
radius: marss::MARS_RADIUS,
position: Vec3::new(1.524 * AU, 0.0, 0.0),
velocity: Vec3::new(0.0, 24_077.0, 0.0),
acceleration: Vec3::ZERO,
j2: J2_MARS,
},
CelestialBody {
id: BodyId::Jupiter,
name: "Jupiter",
mass: jupiters::JUPITERMASS,
radius: jupiters::JUPITERMEANRADIUS,
position: Vec3::new(5.203 * AU, 0.0, 0.0),
velocity: Vec3::new(0.0, 13_070.0, 0.0),
acceleration: Vec3::ZERO,
j2: J2_JUPITER,
},
CelestialBody {
id: BodyId::Saturn,
name: "Saturn",
mass: saturns::SATURNMASS,
radius: saturns::SATURNMEANRADIUS,
position: Vec3::new(9.537 * AU, 0.0, 0.0),
velocity: Vec3::new(0.0, 9_680.0, 0.0),
acceleration: Vec3::ZERO,
j2: J2_SATURN,
},
CelestialBody {
id: BodyId::Uranus,
name: "Uranus",
mass: uranuss::URANUSMASS,
radius: uranuss::URANUSMEANRADIUS,
position: Vec3::new(19.191 * AU, 0.0, 0.0),
velocity: Vec3::new(0.0, 6_810.0, 0.0),
acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::Neptune,
name: "Neptune",
mass: neptunes::NEPTUNEMASS,
radius: neptunes::NEPTUNEMEANRADIUS,
position: Vec3::new(30.069 * AU, 0.0, 0.0),
velocity: Vec3::new(0.0, 5_430.0, 0.0),
acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::Moon,
name: "Moon",
mass: moons::MOON_MASS,
radius: moons::MOON_RADIUS_M,
position: Vec3::new(AU + 3.844e8, 0.0, 0.0),
velocity: Vec3::new(0.0, 29_784.8 + 1_022.0, 0.0),
acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::Phobos,
name: "Phobos",
mass: phoboss::PHOBOS_MASS,
radius: phoboss::PHOBOS_RADIUS_M,
position: Vec3::new(1.524 * AU + 9.376e6, 0.0, 0.0),
velocity: Vec3::new(0.0, 24_077.0 + 2_138.0, 0.0),
acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::Deimos,
name: "Deimos",
mass: deimoss::DEIMOS_MASS,
radius: deimoss::DEIMOS_RADIUS_M,
position: Vec3::new(1.524 * AU + 2.3464e7, 0.0, 0.0),
velocity: Vec3::new(0.0, 24_077.0 + 1_351.3, 0.0),
acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::Io,
name: "Io",
mass: ioss::IO_MASS,
radius: ioss::IO_RADIUS_M,
position: Vec3::new(5.203 * AU + 4.217e8, 0.0, 0.0),
velocity: Vec3::new(0.0, 13_070.0 + 17_334.0, 0.0),
acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::Europa,
name: "Europa",
mass: europas::EUROPA_MASS,
radius: europas::EUROPA_RADIUS_M,
position: Vec3::new(5.203 * AU + 6.711e8, 0.0, 0.0),
velocity: Vec3::new(0.0, 13_070.0 + 13_740.0, 0.0),
acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::Ganymede,
name: "Ganymede",
mass: ganymedes::GANYMEDE_MASS,
radius: ganymedes::GANYMEDE_RADIUS_M,
position: Vec3::new(5.203 * AU + 1.0704e9, 0.0, 0.0),
velocity: Vec3::new(0.0, 13_070.0 + 10_880.0, 0.0),
acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::Callisto,
name: "Callisto",
mass: callistos::CALLISTO_MASS,
radius: callistos::CALLISTO_RADIUS_M,
position: Vec3::new(5.203 * AU + 1.8827e9, 0.0, 0.0),
velocity: Vec3::new(0.0, 13_070.0 + 8_204.0, 0.0),
acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::Titan,
name: "Titan",
mass: titanss::TITAN_MASS,
radius: titanss::TITAN_RADIUS_M,
position: Vec3::new(9.537 * AU + 1.2219e9, 0.0, 0.0),
velocity: Vec3::new(0.0, 9_680.0 + 5_570.0, 0.0),
acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::Enceladus,
name: "Enceladus",
mass: enceladuss::ENCELADUS_MASS,
radius: enceladuss::ENCELADUS_RADIUS_M,
position: Vec3::new(9.537 * AU + 2.3802e8, 0.0, 0.0),
velocity: Vec3::new(0.0, 9_680.0 + 12_635.0, 0.0),
acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::Titania,
name: "Titania",
mass: titanias::TITANIA_MASS,
radius: titanias::TITANIA_RADIUS_M,
position: Vec3::new(19.191 * AU + 4.363e8, 0.0, 0.0),
velocity: Vec3::new(0.0, 6_810.0 + 3_640.0, 0.0),
acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::Oberon,
name: "Oberon",
mass: oberons::OBERON_MASS,
radius: oberons::OBERON_RADIUS_M,
position: Vec3::new(19.191 * AU + 5.835e8, 0.0, 0.0),
velocity: Vec3::new(0.0, 6_810.0 + 3_150.0, 0.0),
acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::Triton,
name: "Triton",
mass: tritons::TRITON_MASS,
radius: tritons::TRITON_RADIUS_M,
position: Vec3::new(30.069 * AU + 3.5476e8, 0.0, 0.0),
velocity: Vec3::new(0.0, 5_430.0 - 4_390.0, 0.0), acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::Pluto,
name: "Pluto",
mass: 1.303e22,
radius: 1.1883e6,
position: Vec3::new(39.482 * AU, 0.0, 0.0),
velocity: Vec3::new(0.0, 4_743.0, 0.0),
acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::Eris,
name: "Eris",
mass: 1.6466e22,
radius: 1.163e6,
position: Vec3::new(67.781 * AU, 0.0, 0.0),
velocity: Vec3::new(0.0, 3_626.0, 0.0),
acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::Haumea,
name: "Haumea",
mass: 4.006e21,
radius: 8.16e5, position: Vec3::new(43.218 * AU, 0.0, 0.0),
velocity: Vec3::new(0.0, 4_538.0, 0.0),
acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::Makemake,
name: "Makemake",
mass: 3.1e21,
radius: 7.15e5,
position: Vec3::new(45.430 * AU, 0.0, 0.0),
velocity: Vec3::new(0.0, 4_419.0, 0.0),
acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::Sedna,
name: "Sedna",
mass: 1.0e21, radius: 4.95e5,
position: Vec3::new(506.8 * AU, 0.0, 0.0),
velocity: Vec3::new(0.0, 1_327.0, 0.0),
acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::Ceres,
name: "Ceres",
mass: 9.3835e20,
radius: 4.73e5,
position: Vec3::new(2.7675 * AU, 0.0, 0.0),
velocity: Vec3::new(0.0, 17_905.0, 0.0),
acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::Vesta,
name: "Vesta",
mass: 2.5908e20,
radius: 2.6278e5,
position: Vec3::new(2.3615 * AU, 0.0, 0.0),
velocity: Vec3::new(0.0, 19_346.0, 0.0),
acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::Pallas,
name: "Pallas",
mass: 2.04e20,
radius: 2.56e5,
position: Vec3::new(2.7731 * AU, 0.0, 0.0),
velocity: Vec3::new(0.0, 17_887.0, 0.0),
acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::Hygiea,
name: "Hygiea",
mass: 8.32e19,
radius: 2.17e5,
position: Vec3::new(3.1394 * AU, 0.0, 0.0),
velocity: Vec3::new(0.0, 16_803.0, 0.0),
acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::Juno,
name: "Juno",
mass: 2.67e19,
radius: 1.2335e5,
position: Vec3::new(2.6691 * AU, 0.0, 0.0),
velocity: Vec3::new(0.0, 18_222.0, 0.0),
acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::Halley,
name: "Halley",
mass: 2.2e14,
radius: 5.5e3, position: Vec3::new(0.586 * AU, 0.0, 0.0),
velocity: Vec3::new(0.0, 54_569.0, 0.0), acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::Encke,
name: "Encke",
mass: 2.0e13, radius: 2.4e3,
position: Vec3::new(0.336 * AU, 0.0, 0.0),
velocity: Vec3::new(0.0, 69_548.0, 0.0), acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::HaleBopp,
name: "Hale-Bopp",
mass: 1.3e16, radius: 3.0e4, position: Vec3::new(0.914 * AU, 0.0, 0.0),
velocity: Vec3::new(0.0, 44_121.0, 0.0), acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::ChuryumovGerasimenko,
name: "67P/C-G",
mass: 9.982e12,
radius: 2.0e3, position: Vec3::new(1.243 * AU, 0.0, 0.0),
velocity: Vec3::new(0.0, 34_271.0, 0.0), acceleration: Vec3::ZERO,
j2: 0.0,
},
CelestialBody {
id: BodyId::Tempel1,
name: "Tempel-1",
mass: 4.5e13, radius: 2.83e3, position: Vec3::new(1.542 * AU, 0.0, 0.0),
velocity: Vec3::new(0.0, 30_554.0, 0.0), acceleration: Vec3::ZERO,
j2: 0.0,
},
]
}
pub fn default_bodies_with_belts(
n_belt_asteroids: u16,
n_kuiper_objects: u16,
) -> Vec<CelestialBody> {
let mut bodies = default_bodies();
bodies.extend(crate::belts::generate_main_belt(n_belt_asteroids));
bodies.extend(crate::belts::generate_kuiper_belt(n_kuiper_objects));
bodies
}
pub fn find_body(bodies: &[CelestialBody], id: BodyId) -> Option<&CelestialBody> {
bodies.iter().find(|b| b.id == id)
}
pub fn find_body_mut(bodies: &mut [CelestialBody], id: BodyId) -> Option<&mut CelestialBody> {
bodies.iter_mut().find(|b| b.id == id)
}
pub fn system_barycenter(bodies: &[CelestialBody]) -> (Vec3, Vec3) {
let total_mass: f64 = bodies.iter().map(|b| b.mass).sum();
let pos = bodies
.iter()
.fold(Vec3::ZERO, |acc, b| acc + b.position * b.mass)
/ total_mass;
let vel = bodies
.iter()
.fold(Vec3::ZERO, |acc, b| acc + b.velocity * b.mass)
/ total_mass;
(pos, vel)
}
pub fn total_energy(bodies: &[CelestialBody]) -> f64 {
let kinetic: f64 = bodies.iter().map(|b| b.kinetic_energy()).sum();
let mut potential = 0.0;
for i in 0..bodies.len() {
for j in (i + 1)..bodies.len() {
potential += bodies[i].potential_energy(&bodies[j]);
}
}
kinetic + potential
}
pub fn total_angular_momentum(bodies: &[CelestialBody]) -> Vec3 {
bodies
.iter()
.fold(Vec3::ZERO, |acc, b| acc + b.angular_momentum())
}