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_rapier3d",
"glam",
"indexmap 2.0.0",
"orbital",
]

View file

@ -19,5 +19,4 @@ bevy_rapier3d = { version = "0.22.0", features = [
"debug-render-3d",
] }
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" }

View file

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

View file

@ -9,6 +9,7 @@ use bevy::{
};
use bevy_rapier3d::prelude::*;
use forces::ExternalForceSet;
use glam::DVec2;
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_vel.normalize_or_zero() * 120.0,
rotated_vel.normalize_or_zero() * 12000.0,
Color::OLIVE,
);
let orbit = orbit::Orbit::from_pos_dir(
body_gravity.mass.into(),
rotated_pos.x.into(),
rotated_pos.z.into(),
rotated_vel.x.into(),
rotated_vel.z.into(),
DVec2::new(rotated_pos.x.into(), rotated_pos.z.into()),
DVec2::new(rotated_vel.x.into(), rotated_vel.z.into()),
);
text.sections[1].value = format!("{:.2}", orbit.semi_major_axis);
text.sections[3].value = format!("{:.2}", orbit.apoapsis());
text.sections[5].value = format!("{:.2}", orbit.periapsis());
gizmos.ray_gradient(ship_pos, velocity, Color::RED, 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;
impl Orbit {
pub fn from_pos_dir(m: f64, x: f64, y: f64, vx: f64, vy: f64) -> Orbit {
let v = DVec2::new(vx, vy);
let v = v.length();
fn cartesian_to_polar(pos: DVec2) -> (f64, f64) {
(pos.length(), f64::atan(pos.y / pos.x))
}
let r_squared = x * x + y * y;
let r = r_squared.sqrt();
let theta = y.atan2(x);
let psi = vy.atan2(vx);
impl Orbit {
pub fn from_pos_dir(m: f64, pos: DVec2, v: DVec2) -> Orbit {
let (r, theta) = cartesian_to_polar(pos);
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
@ -48,17 +47,21 @@ impl Orbit {
#[cfg(test)]
mod tests {
use glam::DVec2;
#[test]
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!(
(21000.0 - orbit.semi_major_axis) < 20.0,
"{} == {}",
21000.0,
orbit.semi_major_axis
);
// this is sus.
assert!(
(1.0 - orbit.eccentricity) < 0.1,
(1.0 - orbit.eccentricity).abs() < 0.1,
"{} == {}",
1.0,
orbit.eccentricity