1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use ascii_art::*;
use super::*;
use util::*;
use coords::*;
use sun::sun_coords;
use std::f64::consts::PI;
pub fn get_lunar_info(julian: f64, location: Location) -> LunarInfo {
let moon_position = getMoonPosition(julian, location.lat, location.lon);
let phase_name = getMoonPhaseName(getMoonPhase(julian));
let phase_image = getMoonPhaseImage(phase_name);
return LunarInfo {
altitude: moon_position.alt,
azimuth: moon_position.az,
percent_illuminated: getMoonIllumination(julian) * 100.0,
phase_name: phase_name.to_string(),
phase_image: phase_image.to_string(),
};
}
pub fn getMoonPhaseImage<'a>(phase_name: &str) -> &'a str {
let image;
image = match phase_name {
"new" => MOON_IMAGE_NEW,
"waxing crescent" => MOON_IMAGE_WAXING_C,
"first quarter" => MOON_IMAGE_FIRST_Q,
"waxing gibbous" => MOON_IMAGE_WAXING_G,
"full" => MOON_IMAGE_FULL,
"waning gibbous" => MOON_IMAGE_WANING_G,
"last quarter" => MOON_IMAGE_LAST_Q,
"waning crescent" => MOON_IMAGE_WANING_C,
_ => "no image found",
};
return ℑ
}
pub fn getMoonPosition(date: f64, lat: f64, lng: f64) -> HzCoordinates {
let lw = RAD * -lng;
let phi = RAD * lat;
let d = julian_epoch_offset(date);
let c = moon_coords(d);
let hour_angle = siderealTime(d, lw) - c.ra;
let mut h = altitude(hour_angle, phi, c.dec);
h = h + astroRefraction(h);
return HzCoordinates {
az: azimuth(hour_angle, phi, c.dec).to_degrees()+180.0,
alt: h.to_degrees(),
};
}
pub fn getMoonIllumination(julian: f64) -> f64 {
let d = julian_epoch_offset(julian);
let s = sun::sun_coords(d);
let m = moon_coords(d);
let phi = (s.dec.sin() * m.dec.sin() + s.dec.cos() * m.dec.cos() * (s.ra - m.ra).cos()).acos();
let inc = (s.dist * phi.sin()).atan2(m.dist - s.dist * phi.cos());
let fraction = (1.0 + inc.cos()) / 2.0;
return fraction;
}
pub fn getMoonPhaseName<'a>(moon_phase: f64) -> &'a str {
let phase = (moon_phase * 100.0) as i32;
let phase_name = match phase {
0...03 => "new",
02...20 => "waxing crescent",
20...30 => "first quarter",
30...47 => "waxing gibbous",
47...53 => "full",
53...70 => "waning gibbous",
70...85 => "last quarter",
85...99 => "waning crescent",
_ => "anything",
};
return phase_name;
}
pub fn getMoonPhase(julian: f64) -> f64 {
let d = julian_epoch_offset(julian);
let s = sun_coords(d);
let m = moon_coords(d);
let phi = (s.dec.sin() * m.dec.sin() + s.dec.cos() * m.dec.cos() * (s.ra - m.ra).cos()).acos();
let inc = (s.dist * phi.sin()).atan2(m.dist - s.dist * phi.cos());
let angle = (s.dec.cos() * (s.ra - m.ra).sin()).atan2(
(s.dec).sin() * m.dec.cos() -
s.dec.cos() * (m.dec).sin() *
(s.ra - m.ra).cos(),
);
let some_phase_var = if angle < 0.0 { -1.0 } else { 1.0 };
return 0.5 + 0.5 * inc * some_phase_var / PI;
}
pub fn moon_coords(d: f64) -> Coords {
let L = RAD * (218.316 + 13.176396 * d);
let M = RAD * (134.963 + 13.064993 * d);
let F = RAD * (93.272 + 13.229350 * d);
let l = L + RAD * 6.289 * M.sin();
let b = RAD * 5.128 * F.sin();
let dt = 385001.0 - 20905.0 * M.cos();
return Coords {
ra: right_ascension(l, b),
dec: declination(l, b),
dist: dt,
};
}