starfall/astronomy/moon/
mod.rs1use crate::astronomy::host_star::HostStar;
2use crate::astronomy::planet::Planet;
3
4pub mod constants;
5pub mod constraints;
6pub mod error;
7use error::Error;
8pub mod math;
9use math::tides::{
10 get_lunar_tide, get_neap_tide, get_planetary_tide, get_solar_tide, get_spring_tide, is_moon_tidally_locked,
11 is_planet_tidally_locked,
12};
13pub mod rotation_direction;
14use rotation_direction::RotationDirection;
15
16#[derive(Clone, Debug, PartialEq)]
25pub struct Moon {
26 pub mass: f64,
28 pub density: f64,
30 pub radius: f64,
32 pub gravity: f64,
34 pub escape_velocity: f64,
36 pub bond_albedo: f64,
38 pub semi_major_axis: f64,
40 pub orbital_eccentricity: f64,
42 pub periapsis: f64,
44 pub apoapsis: f64,
46 pub orbital_inclination: f64,
48 pub rotation_direction: RotationDirection,
50 pub sidereal_orbital_period: f64,
52 pub orbital_period: f64,
54 pub rotation_period: f64,
56 pub lunar_tide: f64,
58 pub solar_tide: f64,
60 pub planetary_tide: f64,
62 pub spring_tide_magnitude: f64,
64 pub neap_tide_magnitude: f64,
66 pub is_planet_tidally_locked: bool,
68 pub is_moon_tidally_locked: bool,
70}
71
72impl Moon {
73 #[named]
74 pub fn from_environment(
75 mass: f64,
76 host_star: &HostStar,
77 star_distance: f64,
78 planet: &Planet,
79 planet_distance: f64,
80 ) -> Result<Moon, Error> {
81 trace_enter!();
82 trace_var!(host_star);
83 trace_var!(star_distance);
84 trace_var!(planet);
85 trace_var!(planet_distance);
86 let density = 3.34;
87 trace_var!(density);
88 let radius = (mass / (density / 3.34)).powf(1.0 / 3.0);
89 trace_var!(radius);
90 let gravity = (mass / radius.powf(2.0)) * 0.1654;
93 trace_var!(gravity);
94 let escape_velocity = (mass / radius).sqrt() * 2.380;
96 trace_var!(escape_velocity);
97 let bond_albedo = 0.136;
99 trace_var!(bond_albedo);
100 let semi_major_axis = planet_distance;
101 trace_var!(semi_major_axis);
102 let orbital_eccentricity = 0.05;
104 trace_var!(orbital_eccentricity);
105 let periapsis = (1.0 - orbital_eccentricity) * semi_major_axis;
106 trace_var!(periapsis);
107 let apoapsis = (1.0 + orbital_eccentricity) * semi_major_axis;
108 trace_var!(apoapsis);
109 let orbital_inclination = 5.15;
111 trace_var!(orbital_inclination);
112 let rotation_direction = RotationDirection::Prograde;
113 trace_var!(rotation_direction);
114 let sidereal_orbital_period =
115 0.0588 * ((semi_major_axis / 12_742.0 * 2.0).powf(3.0) / (planet.get_mass() + mass * 0.0123)).sqrt();
116 trace_var!(sidereal_orbital_period);
117 let earth_orbital_period = planet.get_orbital_period() * 365.265;
118 trace_var!(earth_orbital_period);
119 let orbital_period = earth_orbital_period / (earth_orbital_period / sidereal_orbital_period - 1.0);
120 trace_var!(orbital_period);
121 let lunar_tide = get_lunar_tide(mass, planet.get_radius(), semi_major_axis);
122 trace_var!(lunar_tide);
123 let solar_tide = get_solar_tide(host_star.get_stellar_mass(), planet.get_radius(), star_distance);
124 trace_var!(solar_tide);
125 let planetary_tide = get_planetary_tide(mass, radius, semi_major_axis);
126 trace_var!(planetary_tide);
127 let spring_tide_magnitude = get_spring_tide(lunar_tide, solar_tide);
128 trace_var!(spring_tide_magnitude);
129 let neap_tide_magnitude = get_neap_tide(lunar_tide, solar_tide);
130 trace_var!(neap_tide_magnitude);
131 let is_planet_tidally_locked =
132 is_planet_tidally_locked(lunar_tide, solar_tide, host_star.get_current_age(), planet.get_mass());
133 trace_var!(is_planet_tidally_locked);
134 let is_moon_tidally_locked = is_moon_tidally_locked(solar_tide, planetary_tide, host_star.get_current_age(), mass);
135 trace_var!(is_moon_tidally_locked);
136 let rotation_period = if is_moon_tidally_locked { orbital_period } else { 3.0 };
137 trace_var!(rotation_period);
138 let result = Moon {
139 mass,
140 density,
141 radius,
142 gravity,
143 escape_velocity,
144 bond_albedo,
145 semi_major_axis,
146 orbital_eccentricity,
147 periapsis,
148 apoapsis,
149 orbital_inclination,
150 rotation_direction,
151 sidereal_orbital_period,
152 orbital_period,
153 rotation_period,
154 lunar_tide,
155 solar_tide,
156 planetary_tide,
157 spring_tide_magnitude,
158 neap_tide_magnitude,
159 is_planet_tidally_locked,
160 is_moon_tidally_locked,
161 };
162 trace_var!(result);
163 trace_exit!();
164 Ok(result)
165 }
166}