nyx_space/cosmic/
eclipse.rs1use anise::almanac::Almanac;
20use anise::analysis::prelude::Event;
21use anise::astro::Occultation;
22use anise::constants::frames::{EARTH_J2000, MOON_J2000, SUN_J2000};
23use anise::errors::AlmanacResult;
24use serde::{Deserialize, Serialize};
25use serde_dhall::StaticType;
26
27pub use super::{Frame, Orbit, Spacecraft};
28use std::fmt;
29
30#[cfg(feature = "python")]
31use pyo3::prelude::*;
32
33#[cfg_attr(feature = "python", pyclass(from_py_object, get_all, set_all))]
34#[derive(Clone, Debug, Serialize, Deserialize, StaticType)]
35pub struct ShadowModel {
36 pub light_source: Frame,
37 pub shadow_bodies: Vec<Frame>,
38}
39
40impl fmt::Display for ShadowModel {
41 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
42 let shadow_bodies: Vec<String> = self
43 .shadow_bodies
44 .iter()
45 .map(|b| format!("{b:x}"))
46 .collect();
47 write!(
48 f,
49 "light-source: {:x}, shadows casted by: {}",
50 self.light_source,
51 shadow_bodies.join(", ")
52 )
53 }
54}
55
56impl ShadowModel {
57 pub fn cislunar(almanac: &Almanac) -> Self {
60 let eme2k = almanac.frame_info(EARTH_J2000).unwrap();
61 let moon_j2k = almanac.frame_info(MOON_J2000).unwrap();
62 Self {
63 light_source: almanac.frame_info(SUN_J2000).unwrap(),
64 shadow_bodies: vec![eme2k, moon_j2k],
65 }
66 }
67
68 pub fn compute(&self, observer: Orbit, almanac: &Almanac) -> AlmanacResult<Occultation> {
70 let mut state = Occultation {
71 epoch: observer.epoch,
72 back_frame: SUN_J2000,
73 front_frame: observer.frame,
74 percentage: 0.0,
75 };
76 for eclipsing_body in &self.shadow_bodies {
77 let this_state = almanac.solar_eclipsing(*eclipsing_body, observer, None)?;
78 if this_state.percentage > state.percentage {
79 state = this_state;
80 }
81 }
82 Ok(state)
83 }
84
85 pub fn to_umbra_events(&self) -> Vec<Event> {
88 self.shadow_bodies
89 .iter()
90 .copied()
91 .map(Event::total_eclipse)
92 .collect()
93 }
94
95 pub fn to_penumbra_events(&self) -> Vec<Event> {
98 self.shadow_bodies
99 .iter()
100 .copied()
101 .map(Event::eclipse)
102 .collect()
103 }
104}