marss 0.0.3

Mars celestial simulation crate for the MilkyWay SolarSystem workspace
Documentation
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DaylightState {
    Day,
    CivilTwilight,
    NauticalTwilight,
    AstronomicalTwilight,
    Night,
}

pub struct DayNightCycle {
    pub ls_deg: f64,
}

impl DayNightCycle {
    pub fn new(ls_deg: f64) -> Self {
        Self { ls_deg }
    }

    pub fn state_at(&self, lat_deg: f64, local_time_h: f64) -> DaylightState {
        let sun =
            super::solar_position::SolarPosition::compute(self.ls_deg, local_time_h, lat_deg, 0.0);
        let elev = sun.elevation_deg;
        if elev > 0.0 {
            DaylightState::Day
        } else if elev > -6.0 {
            DaylightState::CivilTwilight
        } else if elev > -12.0 {
            DaylightState::NauticalTwilight
        } else if elev > -18.0 {
            DaylightState::AstronomicalTwilight
        } else {
            DaylightState::Night
        }
    }

    pub fn ambient_light(&self, lat_deg: f64, local_time_h: f64) -> f64 {
        let sun =
            super::solar_position::SolarPosition::compute(self.ls_deg, local_time_h, lat_deg, 0.0);
        let elev = sun.elevation_deg;
        if elev > 10.0 {
            1.0
        } else if elev > 0.0 {
            0.3 + 0.7 * (elev / 10.0)
        } else if elev > -18.0 {
            0.3 * ((elev + 18.0) / 18.0).max(0.0)
        } else {
            0.0
        }
    }

    pub fn day_length_hours(&self, lat_deg: f64) -> f64 {
        let decl = super::solar_position::solar_declination_deg(self.ls_deg).to_radians();
        let lat = lat_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
    }
}