use crate::Real;
use core::f64::consts::TAU;
#[derive(Debug, Clone, Copy)]
pub struct Sidereal {
pub rate_rad_per_sec: Real,
pub ref_epoch: Real,
pub ref_angle_rad: Real,
pub longitude_rad: Real,
pub pole_delta_x_rad: Real,
pub pole_delta_y_rad: Real,
pub correction_rad: Real,
}
impl Sidereal {
pub const EARTH: Self = Self {
rate_rad_per_sec: (1.00273781191135448 * core::f64::consts::TAU) / 86400.0,
ref_epoch: 51544.5,
ref_angle_rad: 0.7790572732640 * core::f64::consts::TAU,
longitude_rad: 0.0,
pole_delta_x_rad: 0.0,
pole_delta_y_rad: 0.0,
correction_rad: 0.0,
};
pub const MARS: Self = Self {
rate_rad_per_sec: core::f64::consts::TAU / 88642.663,
ref_epoch: 51544.5,
ref_angle_rad: 0.0,
longitude_rad: 0.0,
pole_delta_x_rad: 0.0,
pole_delta_y_rad: 0.0,
correction_rad: 0.0,
};
pub const MOON: Self = Self {
rate_rad_per_sec: core::f64::consts::TAU / 2_360_591.424,
ref_epoch: 51544.5,
ref_angle_rad: 0.0,
longitude_rad: 0.0,
pole_delta_x_rad: 0.0,
pole_delta_y_rad: 0.0,
correction_rad: 0.0,
};
#[inline]
const fn normalize_angle(angle: Real) -> Real {
((angle % TAU) + TAU) % TAU
}
pub const fn rotation_angle(&self, mjd: Real) -> Real {
let elapsed_days = mjd - self.ref_epoch;
let elapsed_sec = elapsed_days * 86400.0;
let angle = self.ref_angle_rad
+ self.rate_rad_per_sec * elapsed_sec
+ self.pole_delta_x_rad
+ self.pole_delta_y_rad
+ self.correction_rad;
Self::normalize_angle(angle)
}
#[inline]
pub const fn local_rotation_angle(&self, mjd: Real) -> Real {
Self::normalize_angle(self.rotation_angle(mjd) + self.longitude_rad)
}
#[inline]
pub const fn sidereal_angle_mean(&self, mjd: Real, eo_rad: Real) -> Real {
let angle = self.rotation_angle(mjd) + eo_rad;
Self::normalize_angle(angle)
}
#[inline]
pub const fn local_sidereal_angle_mean(&self, mjd: Real, eo_rad: Real) -> Real {
let angle = self.rotation_angle(mjd) + self.longitude_rad + eo_rad;
Self::normalize_angle(angle)
}
pub const fn sidereal_time_mean(&self, mjd: Real, eo_rad: Real) -> Real {
let angle = self.sidereal_angle_mean(mjd, eo_rad);
let fraction = ((angle / TAU) % 1.0 + 1.0) % 1.0;
fraction * 86400.0
}
pub const fn local_sidereal_time_mean(&self, mjd: Real, eo_rad: Real) -> Real {
let angle = self.local_sidereal_angle_mean(mjd, eo_rad);
let fraction = ((angle / TAU) % 1.0 + 1.0) % 1.0;
fraction * 86400.0
}
pub fn sidereal_angle_apparent(&self, mjd: Real, eo_rad: Real, ee_rad: Real) -> Real {
let angle = self.rotation_angle(mjd) + eo_rad + ee_rad;
Self::normalize_angle(angle)
}
pub fn local_sidereal_angle_apparent(&self, mjd: Real, eo_rad: Real, ee_rad: Real) -> Real {
let angle = self.rotation_angle(mjd) + self.longitude_rad + eo_rad + ee_rad;
Self::normalize_angle(angle)
}
pub fn sidereal_time_apparent(&self, mjd: Real, eo_rad: Real, ee_rad: Real) -> Real {
let angle = self.sidereal_angle_apparent(mjd, eo_rad, ee_rad);
let fraction = ((angle / TAU) % 1.0 + 1.0) % 1.0;
fraction * 86400.0
}
pub fn local_sidereal_time_apparent(&self, mjd: Real, eo_rad: Real, ee_rad: Real) -> Real {
let angle = self.local_sidereal_angle_apparent(mjd, eo_rad, ee_rad);
let fraction = ((angle / TAU) % 1.0 + 1.0) % 1.0;
fraction * 86400.0
}
}