better orbit

This commit is contained in:
nora 2023-09-17 20:08:52 +02:00
parent 2d63b5a054
commit a8855a216b
5 changed files with 19 additions and 21 deletions

1
Cargo.lock generated
View file

@ -3071,7 +3071,6 @@ dependencies = [
"bevy", "bevy",
"bevy_rapier3d", "bevy_rapier3d",
"glam", "glam",
"indexmap 2.0.0",
"orbital", "orbital",
] ]

View file

@ -19,5 +19,4 @@ bevy_rapier3d = { version = "0.22.0", features = [
"debug-render-3d", "debug-render-3d",
] } ] }
glam = { version = "0.24.1", features = ["debug-glam-assert"] } glam = { version = "0.24.1", features = ["debug-glam-assert"] }
indexmap = "2.0.0"
orbital = { git = "https://github.com/oli-obk/solar_sailors.git", rev = "2fabdd044f0f362595494dcad5102c50ae9572f7" } orbital = { git = "https://github.com/oli-obk/solar_sailors.git", rev = "2fabdd044f0f362595494dcad5102c50ae9572f7" }

View file

@ -1,12 +1,11 @@
use std::any::TypeId; use std::{any::TypeId, collections::BTreeMap};
use bevy::prelude::*; use bevy::prelude::*;
use bevy_rapier3d::prelude::ExternalForce; use bevy_rapier3d::prelude::ExternalForce;
use indexmap::IndexMap;
#[derive(Component, Default)] #[derive(Component, Default)]
pub struct ExternalForceSet { pub struct ExternalForceSet {
forces: IndexMap<TypeId, ExternalForce, ahash::RandomState>, forces: BTreeMap<TypeId, ExternalForce>,
} }
impl ExternalForceSet { impl ExternalForceSet {

View file

@ -9,6 +9,7 @@ use bevy::{
}; };
use bevy_rapier3d::prelude::*; use bevy_rapier3d::prelude::*;
use forces::ExternalForceSet; use forces::ExternalForceSet;
use glam::DVec2;
use crate::forces::update_external_forces; use crate::forces::update_external_forces;
@ -198,22 +199,19 @@ fn debug_spaceship_orbit(
gizmos.ray(body_pos, rotated_pos, Color::FUCHSIA); gizmos.ray(body_pos, rotated_pos, Color::FUCHSIA);
gizmos.ray( gizmos.ray(
body_pos, body_pos,
rotated_vel.normalize_or_zero() * 120.0, rotated_vel.normalize_or_zero() * 12000.0,
Color::OLIVE, Color::OLIVE,
); );
let orbit = orbit::Orbit::from_pos_dir( let orbit = orbit::Orbit::from_pos_dir(
body_gravity.mass.into(), body_gravity.mass.into(),
rotated_pos.x.into(), DVec2::new(rotated_pos.x.into(), rotated_pos.z.into()),
rotated_pos.z.into(), DVec2::new(rotated_vel.x.into(), rotated_vel.z.into()),
rotated_vel.x.into(),
rotated_vel.z.into(),
); );
text.sections[1].value = format!("{:.2}", orbit.semi_major_axis); text.sections[1].value = format!("{:.2}", orbit.semi_major_axis);
text.sections[3].value = format!("{:.2}", orbit.apoapsis()); text.sections[3].value = format!("{:.2}", orbit.apoapsis());
text.sections[5].value = format!("{:.2}", orbit.periapsis()); text.sections[5].value = format!("{:.2}", orbit.periapsis());
gizmos.ray_gradient(ship_pos, velocity, Color::RED, Color::GREEN); gizmos.ray_gradient(ship_pos, velocity, Color::RED, Color::GREEN);
gizmos.ray_gradient(ship_pos, translation, Color::BLUE, Color::GREEN); gizmos.ray_gradient(ship_pos, translation, Color::BLUE, Color::GREEN);

View file

@ -8,15 +8,14 @@ pub struct Orbit {
pub const G: f64 = 6.6e-11; pub const G: f64 = 6.6e-11;
impl Orbit { fn cartesian_to_polar(pos: DVec2) -> (f64, f64) {
pub fn from_pos_dir(m: f64, x: f64, y: f64, vx: f64, vy: f64) -> Orbit { (pos.length(), f64::atan(pos.y / pos.x))
let v = DVec2::new(vx, vy); }
let v = v.length();
let r_squared = x * x + y * y; impl Orbit {
let r = r_squared.sqrt(); pub fn from_pos_dir(m: f64, pos: DVec2, v: DVec2) -> Orbit {
let theta = y.atan2(x); let (r, theta) = cartesian_to_polar(pos);
let psi = vy.atan2(vx); let (v, psi) = cartesian_to_polar(v);
// https://phys.libretexts.org/Bookshelves/Astronomy__Cosmology/Celestial_Mechanics_(Tatum)/09%3A_The_Two_Body_Problem_in_Two_Dimensions/9.08%3A_Orbital_Elements_and_Velocity_Vector // https://phys.libretexts.org/Bookshelves/Astronomy__Cosmology/Celestial_Mechanics_(Tatum)/09%3A_The_Two_Body_Problem_in_Two_Dimensions/9.08%3A_Orbital_Elements_and_Velocity_Vector
@ -48,17 +47,21 @@ impl Orbit {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use glam::DVec2;
#[test] #[test]
fn geostationary() { fn geostationary() {
let orbit = super::Orbit::from_pos_dir(5.972e24, 42000.0, 0.0, 0.0, 3074.0); let orbit =
super::Orbit::from_pos_dir(5.972e24, DVec2::new(42000.0, 0.0), DVec2::new(0.0, 3074.0));
assert!( assert!(
(21000.0 - orbit.semi_major_axis) < 20.0, (21000.0 - orbit.semi_major_axis) < 20.0,
"{} == {}", "{} == {}",
21000.0, 21000.0,
orbit.semi_major_axis orbit.semi_major_axis
); );
// this is sus.
assert!( assert!(
(1.0 - orbit.eccentricity) < 0.1, (1.0 - orbit.eccentricity).abs() < 0.1,
"{} == {}", "{} == {}",
1.0, 1.0,
orbit.eccentricity orbit.eccentricity