mirror of
https://github.com/Noratrieb/spaceship.git
synced 2026-01-14 16:35:08 +01:00
better orbit
This commit is contained in:
parent
2d63b5a054
commit
a8855a216b
5 changed files with 19 additions and 21 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -3071,7 +3071,6 @@ dependencies = [
|
||||||
"bevy",
|
"bevy",
|
||||||
"bevy_rapier3d",
|
"bevy_rapier3d",
|
||||||
"glam",
|
"glam",
|
||||||
"indexmap 2.0.0",
|
|
||||||
"orbital",
|
"orbital",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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" }
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
10
src/main.rs
10
src/main.rs
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
23
src/orbit.rs
23
src/orbit.rs
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue