pub struct VenusRotation {
pub angular_velocity_rad_s: f64,
pub axial_tilt_rad: f64,
}
impl Default for VenusRotation {
fn default() -> Self {
Self::new()
}
}
impl VenusRotation {
pub fn new() -> Self {
Self {
angular_velocity_rad_s: crate::OMEGA_VENUS,
axial_tilt_rad: crate::AXIAL_TILT_DEG.to_radians(),
}
}
pub fn surface_velocity_at_latitude(&self, latitude_deg: f64) -> f64 {
let lat = latitude_deg.to_radians();
self.angular_velocity_rad_s.abs() * crate::VENUS_RADIUS * lat.cos()
}
pub fn coriolis_parameter(&self, latitude_deg: f64) -> f64 {
2.0 * self.angular_velocity_rad_s * latitude_deg.to_radians().sin()
}
pub fn moment_of_inertia(&self) -> f64 {
crate::MOI_FACTOR * crate::VENUS_MASS * crate::VENUS_RADIUS.powi(2)
}
pub fn rotational_kinetic_energy(&self) -> f64 {
0.5 * self.moment_of_inertia() * self.angular_velocity_rad_s * self.angular_velocity_rad_s
}
pub fn angular_momentum(&self) -> f64 {
self.moment_of_inertia() * self.angular_velocity_rad_s
}
pub fn precession_rate_rad_per_year(&self) -> f64 {
2.0 * std::f64::consts::PI / 287_000.0
}
pub fn solar_declination(&self, heliocentric_longitude_deg: f64) -> f64 {
let l = heliocentric_longitude_deg.to_radians();
(self.axial_tilt_rad.sin() * l.sin()).asin().to_degrees()
}
pub fn day_length_hours(&self, latitude_deg: f64, heliocentric_longitude_deg: f64) -> f64 {
let decl = self
.solar_declination(heliocentric_longitude_deg)
.to_radians();
let lat = latitude_deg.to_radians();
let cos_h = -(lat.tan() * decl.tan());
if cos_h <= -1.0 {
return 24.0;
}
if cos_h >= 1.0 {
return 0.0;
}
cos_h.acos().to_degrees() / 180.0 * 24.0
}
}