use crate::aliases::{Position, Velocity};
use crate::frame::{IntegrationFrame, RootInertial};
#[derive(Debug, Clone, Copy, Default)]
pub struct IntegOrigin {
pub position: Position<RootInertial>,
pub velocity: Velocity<RootInertial>,
}
impl IntegOrigin {
#[inline]
pub fn zero() -> Self {
Self {
position: Position::<RootInertial>::zero(),
velocity: Velocity::<RootInertial>::zero(),
}
}
#[inline]
pub fn shift_position(&self, p: Position<IntegrationFrame>) -> Position<RootInertial> {
Position::<RootInertial>::from_raw_si(p.raw_si() + self.position.raw_si())
}
#[inline]
pub fn shift_velocity(&self, v: Velocity<IntegrationFrame>) -> Velocity<RootInertial> {
Velocity::<RootInertial>::from_raw_si(v.raw_si() + self.velocity.raw_si())
}
#[inline]
pub fn shift_position_at_stage(
&self,
p: Position<IntegrationFrame>,
stage_dt: f64,
) -> Position<RootInertial> {
let stage_origin = self.position.raw_si() + self.velocity.raw_si() * stage_dt;
Position::<RootInertial>::from_raw_si(p.raw_si() + stage_origin)
}
}
#[cfg(test)]
mod tests {
use super::*;
use glam::DVec3;
#[test]
fn zero_origin_is_identity_for_position() {
let p = Position::<IntegrationFrame>::from_raw_si(DVec3::new(7e6, 0.0, 0.0));
let shifted = IntegOrigin::zero().shift_position(p);
assert_eq!(shifted.raw_si(), p.raw_si());
}
#[test]
fn zero_origin_is_identity_for_velocity() {
let v = Velocity::<IntegrationFrame>::from_raw_si(DVec3::new(0.0, 7500.0, 0.0));
let shifted = IntegOrigin::zero().shift_velocity(v);
assert_eq!(shifted.raw_si(), v.raw_si());
}
#[test]
fn nonzero_origin_adds_to_position() {
let o = IntegOrigin {
position: Position::<RootInertial>::from_raw_si(DVec3::new(1.5e11, 0.0, 0.0)),
velocity: Velocity::<RootInertial>::zero(),
};
let p_integ = Position::<IntegrationFrame>::from_raw_si(DVec3::new(7e6, 0.0, 0.0));
let p_root = o.shift_position(p_integ);
assert_eq!(p_root.raw_si(), DVec3::new(1.5e11 + 7e6, 0.0, 0.0));
}
#[test]
fn nonzero_origin_adds_to_velocity() {
let o = IntegOrigin {
position: Position::<RootInertial>::zero(),
velocity: Velocity::<RootInertial>::from_raw_si(DVec3::new(0.0, 30_000.0, 0.0)),
};
let v_integ = Velocity::<IntegrationFrame>::from_raw_si(DVec3::new(0.0, 7500.0, 0.0));
let v_root = o.shift_velocity(v_integ);
assert_eq!(v_root.raw_si(), DVec3::new(0.0, 30_000.0 + 7500.0, 0.0));
}
}