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,
}
}