164 lines
3.8 KiB
Rust
164 lines
3.8 KiB
Rust
#![allow(unused)]
|
|
use glam::DVec3;
|
|
use once_cell::sync::Lazy;
|
|
use std::sync::RwLock;
|
|
use log::{debug};
|
|
|
|
use crate::config::{Body, Normalization};
|
|
|
|
pub type Position = DVec3;
|
|
pub type Velocity = DVec3;
|
|
pub type Acceleration = DVec3;
|
|
pub type Mass = f64;
|
|
pub type Time = f64;
|
|
|
|
|
|
// Constants
|
|
const EARTH_RADIUS: f64 = 6.378e6; //meters
|
|
const EARTH_MASS: f64 = 5.972e24; //kg
|
|
const EARTH_ORBITAL_VELOCITY: f64 = 2.9780e4; //m/s
|
|
const AU: f64 = 1.49597870700e11; //meters
|
|
|
|
const MOON_MASS: Mass = 7.34767309e22; // kg
|
|
const MOON_ORBITAL_VELOCITY: f64 = 1.022e3; //m/s relative to earth
|
|
|
|
const SUN_MASS: f64 = 1.989e30; //kg
|
|
const SUN_RADIUS: f64 = 6.957e8; //meters
|
|
|
|
const G: f64 = 6.67430e-11;
|
|
|
|
// Default normalization constants
|
|
const DEFAULT_R_0: f64 = EARTH_RADIUS;
|
|
const DEFAULT_M_0: f64 = EARTH_MASS;
|
|
|
|
// Global normalization context
|
|
static NORMALIZATION: Lazy<RwLock<NormalizationContext>> = Lazy::new(|| {
|
|
RwLock::new(NormalizationContext::default())
|
|
});
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct NormalizationContext {
|
|
pub r_0: f64,
|
|
pub m_0: f64,
|
|
pub t_0: f64,
|
|
}
|
|
|
|
impl Default for NormalizationContext {
|
|
fn default() -> Self {
|
|
let r_0 = DEFAULT_R_0;
|
|
let m_0 = DEFAULT_M_0;
|
|
let t_0 = (r_0.powf(3.0) / (G * m_0)).sqrt();
|
|
debug!("Using default normalization: r_0 = {}, m_0 = {}, t_0 = {}", r_0, m_0, t_0);
|
|
Self { r_0, m_0, t_0 }
|
|
}
|
|
}
|
|
|
|
impl From<&Normalization> for NormalizationContext {
|
|
fn from(norm: &Normalization) -> Self {
|
|
Self {
|
|
r_0: norm.r_0,
|
|
m_0: norm.m_0,
|
|
t_0: norm.t_0
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Set the global normalization context from a config normalization
|
|
pub fn set_normalization(norm: &Normalization) {
|
|
let mut context = NORMALIZATION.write().unwrap();
|
|
*context = NormalizationContext::from(norm);
|
|
}
|
|
|
|
/// Reset to default normalization
|
|
pub fn reset_normalization() {
|
|
let mut context = NORMALIZATION.write().unwrap();
|
|
*context = NormalizationContext::default();
|
|
}
|
|
|
|
/// Get current normalization context
|
|
pub fn get_normalization() -> NormalizationContext {
|
|
NORMALIZATION.read().unwrap().clone()
|
|
}
|
|
|
|
|
|
#[inline]
|
|
pub fn norm_pos(pos: Position) -> Position {
|
|
let norm = get_normalization();
|
|
pos / norm.r_0
|
|
}
|
|
|
|
#[inline]
|
|
pub fn real_pos(pos: Position) -> Position {
|
|
let norm = get_normalization();
|
|
pos * norm.r_0
|
|
}
|
|
|
|
#[inline]
|
|
pub fn norm_mass(mass: Mass) -> Mass {
|
|
let norm = get_normalization();
|
|
mass / norm.m_0
|
|
}
|
|
|
|
#[inline]
|
|
pub fn real_mass(mass: Mass) -> Mass {
|
|
let norm = get_normalization();
|
|
mass * norm.m_0
|
|
}
|
|
|
|
#[inline]
|
|
pub fn norm_time(time: Time) -> Time {
|
|
let norm = get_normalization();
|
|
time / norm.t_0
|
|
}
|
|
|
|
#[inline]
|
|
pub fn real_time(time: Time) -> Time {
|
|
let norm = get_normalization();
|
|
time * norm.t_0
|
|
}
|
|
|
|
#[inline]
|
|
pub fn norm_vel(vel: Velocity) -> Velocity {
|
|
let norm = get_normalization();
|
|
vel / (norm.r_0 / norm.t_0)
|
|
}
|
|
|
|
#[inline]
|
|
pub fn real_vel(vel: Velocity) -> Velocity {
|
|
let norm = get_normalization();
|
|
vel * (norm.r_0 / norm.t_0)
|
|
}
|
|
|
|
#[inline]
|
|
pub fn norm_acc(acc: Acceleration) -> Acceleration {
|
|
let norm = get_normalization();
|
|
acc / (norm.r_0 / (norm.t_0 * norm.t_0))
|
|
}
|
|
|
|
#[inline]
|
|
pub fn real_acc(acc: Acceleration) -> Acceleration {
|
|
let norm = get_normalization();
|
|
acc * (norm.r_0 / (norm.t_0 * norm.t_0))
|
|
}
|
|
|
|
#[inline]
|
|
pub fn norm_body(body: Body) -> Body {
|
|
Body {
|
|
name: body.name,
|
|
mass: norm_mass(body.mass),
|
|
position: norm_pos(body.position),
|
|
velocity: norm_vel(body.velocity),
|
|
acceleration: DVec3::ZERO,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn real_body(body: &Body) -> Body {
|
|
Body {
|
|
name: body.name.clone(),
|
|
mass: real_mass(body.mass),
|
|
position: real_pos(body.position),
|
|
velocity: real_vel(body.velocity),
|
|
acceleration: DVec3::ZERO,
|
|
}
|
|
} |