const JUPITERAXIALTILTDEG: f64 = 3.13;
const JUPITERORBITALPERIODDAYS: f64 = 4332.59;
pub struct Seasons {
pub juliandate: f64,
}
impl Seasons {
pub fn new(juliandate: f64) -> Self {
Self { juliandate }
}
pub fn jupitersolarlongitudedeg(&self) -> f64 {
let j2000epoch = 2451545.0;
let days = self.juliandate - j2000epoch;
let meananomaly = (18.818 + 360.0 * days / JUPITERORBITALPERIODDAYS) % 360.0;
let meananomaly_rad = meananomaly.to_radians();
let ecc: f64 = 0.0489;
let trueanomaly = meananomaly
+ (2.0 * ecc - ecc.powi(3) / 4.0) * meananomaly_rad.sin().to_degrees()
+ (5.0 / 4.0) * ecc.powi(2) * (2.0 * meananomaly_rad).sin().to_degrees();
let perihelong = 14.75;
(trueanomaly + perihelong + 360.0) % 360.0
}
pub fn subsolarlatitudedeg(&self) -> f64 {
let ls = self.jupitersolarlongitudedeg();
let tilt = JUPITERAXIALTILTDEG.to_radians();
(tilt.sin() * ls.to_radians().sin()).asin().to_degrees()
}
pub fn seasonname(&self) -> &'static str {
let ls = self.jupitersolarlongitudedeg();
match ls {
l if l < 90.0 => "Northern Spring",
l if l < 180.0 => "Northern Summer",
l if l < 270.0 => "Northern Autumn",
_ => "Northern Winter",
}
}
pub fn daylighthours(&self, latdeg: f64) -> f64 {
let decl = self.subsolarlatitudedeg().to_radians();
let lat = latdeg.to_radians();
let cosh = -(lat.tan() * decl.tan());
if cosh < -1.0 {
return 9.925;
}
if cosh > 1.0 {
return 0.0;
}
let ha = cosh.acos();
9.925 * ha / std::f64::consts::PI
}
pub fn insolationfactor(&self, latdeg: f64) -> f64 {
let lat = latdeg.to_radians();
let decl = self.subsolarlatitudedeg().to_radians();
let zenithcos = lat.cos() * decl.cos() + lat.sin() * decl.sin();
let distanceau = 5.2044;
zenithcos.max(0.0) / (distanceau * distanceau)
}
}