#[allow(unused_macros)]
#[reefer::algebra(f64, 1, 3)]
mod spacetime {
basis!(e0 = P0); basis!(e1 = N0); basis!(e2 = N1); basis!(e3 = N2);
#[derive(Debug, Clone, Copy)]
shape!(Scalar { 1 });
#[derive(Debug, Clone, Copy)]
shape!(Event { e0, e1, e2, e3 });
pub const LIGHT_SPEED_KM_PER_S: f64 = 299_792.458;
impl Event {
pub fn new(e0: f64, e1: f64, e2: f64, e3: f64) -> Self {
Self { e0, e1, e2, e3 }
}
pub fn from_us_km(micros: f64, km_x: f64, km_y: f64, km_z: f64) -> Self {
Self {
e0: micros * 1.0e-6,
e1: km_x / LIGHT_SPEED_KM_PER_S,
e2: km_y / LIGHT_SPEED_KM_PER_S,
e3: km_z / LIGHT_SPEED_KM_PER_S,
}
}
pub fn to_us_km(&self) -> (f64, f64, f64, f64) {
(
self.e0 * 1.0e6,
self.e1 * LIGHT_SPEED_KM_PER_S,
self.e2 * LIGHT_SPEED_KM_PER_S,
self.e3 * LIGHT_SPEED_KM_PER_S,
)
}
pub fn components(&self) -> (f64, f64, f64, f64) {
(self.e0, self.e1, self.e2, self.e3)
}
pub fn time(&self) -> f64 {
self.e0
}
}
}
impl From<f64> for spacetime::Scalar {
fn from(value: f64) -> Self {
Self { _1: value }
}
}
impl core::fmt::Display for spacetime::Event {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let (t, x, y, z) = self.to_us_km();
write!(
f,
"Event {{ t: {:.9} μs, x: {:.9} km, y: {:.9} km, z: {:.9} km }}",
t, x, y, z,
)
}
}
fn main() {
println!("Earth frame observations:");
let strike_tree = { spacetime::Event::from_us_km(10.0, 0.0, 0.0, 0.0) };
println!(" Tree: {}", strike_tree);
let strike_pole = spacetime::Event::from_us_km(10.0, 20.0, 0.0, 0.0);
println!(" Pole: {}", strike_pole);
let rocket_speed: f64 = 0.5; let phi = rocket_speed.atanh();
let a = -0.5 * phi;
let boost_calc = spacetime::expr! {
|ev: spacetime::Event, a: spacetime::Scalar| (a * e10).exp().sandwich(ev)
};
let boost = |ev: spacetime::Event| boost_calc(ev, a.into());
let strike_tree_r = boost(strike_tree);
let strike_pole_r = boost(strike_pole);
println!("Rocket frame observations at β = {} c:", rocket_speed);
println!(" Tree: {:?}", strike_tree_r);
println!(" Pole: {:?}", strike_pole_r);
let simultaneous = (strike_tree_r.time() - strike_pole_r.time()).abs() < 1.0e-12;
println!(
" {}",
if simultaneous {
"Hey that's at the same time !"
} else {
"Wow! That's not at the same time!"
}
);
let event = spacetime::Event::new(1.0, 1.0, 0.0, 0.0);
let event_in_frame = boost(event);
let (t_ls, x_ls, _, _) = event_in_frame.components();
println!(
"\nEvent at (t=1, x=1) as seen at 0.5c: {:?}",
event_in_frame
);
println!(" time component (lightseconds) = {:.12}", t_ls);
println!(" space component (lightseconds) = {:.12}", x_ls);
}