siderust-cpp 0.8.0
Header-only C++ wrapper for siderust
Loading...
Searching...
No Matches
lunar_phase.hpp
Go to the documentation of this file.
1#pragma once
2
14#include "altitude.hpp"
15#include "coordinates.hpp"
16#include "ffi_core.hpp"
17#include "time.hpp"
18#include <ostream>
19#include <vector>
20
21namespace siderust {
22
23// ============================================================================
24// Phase enumerations
25// ============================================================================
26
30enum class PhaseKind : int32_t {
31 NewMoon = 0,
32 FirstQuarter = 1,
33 FullMoon = 2,
34 LastQuarter = 3,
35};
36
40enum class MoonPhaseLabel : int32_t {
41 NewMoon = 0,
43 FirstQuarter = 2,
44 WaxingGibbous = 3,
45 FullMoon = 4,
46 WaningGibbous = 5,
47 LastQuarter = 6,
49};
50
51// ============================================================================
52// Phase event / geometry types
53// ============================================================================
54
59 qtty::Radian phase_angle;
61 qtty::Radian elongation;
62 bool waxing;
63
64 static MoonPhaseGeometry from_c(const siderust_moon_phase_geometry_t &c) {
65 return {qtty::Radian(c.phase_angle_rad), c.illuminated_fraction, qtty::Radian(c.elongation_rad),
66 static_cast<bool>(c.waxing)};
67 }
68};
69
73struct PhaseEvent {
76
77 static PhaseEvent from_c(const siderust_phase_event_t &c) {
78 return {Time<TT, MJD>(c.mjd), static_cast<PhaseKind>(c.kind)};
79 }
80};
81
82// ============================================================================
83// Internal helpers
84// ============================================================================
85namespace detail {
86
87inline std::vector<PhaseEvent> phase_events_from_c(siderust_phase_event_t *ptr, uintptr_t count) {
88 std::vector<PhaseEvent> result;
89 result.reserve(count);
90 for (uintptr_t i = 0; i < count; ++i) {
91 result.push_back(PhaseEvent::from_c(ptr[i]));
92 }
93 siderust_phase_events_free(ptr, count);
94 return result;
95}
96
99inline std::vector<Period<TT, MJD>> illum_periods_from_c(tempoch_period_mjd_t *ptr,
100 uintptr_t count) {
101 std::vector<Period<TT, MJD>> result;
102 result.reserve(count);
103 for (uintptr_t i = 0; i < count; ++i) {
104 result.push_back(
105 Period<TT, MJD>(Time<TT, MJD>(ptr[i].start_mjd), Time<TT, MJD>(ptr[i].end_mjd)));
106 }
107 siderust_periods_free(ptr, count);
108 return result;
109}
110
111} // namespace detail
112
113// ============================================================================
114// Lunar phase namespace
115// ============================================================================
116
117namespace moon {
118
125 siderust_moon_phase_geometry_t out{};
126 check_status(siderust_moon_phase_geocentric(jd.value(), &out), "moon::phase_geocentric");
127 return MoonPhaseGeometry::from_c(out);
128}
129
137 siderust_moon_phase_geometry_t out{};
138 check_status(siderust_moon_phase_topocentric(jd.value(), site.to_c(), &out),
139 "moon::phase_topocentric");
140 return MoonPhaseGeometry::from_c(out);
141}
142
150 siderust_moon_phase_geometry_t c{geom.phase_angle.value(), geom.illuminated_fraction,
151 geom.elongation.value(), static_cast<uint8_t>(geom.waxing)};
152 siderust_moon_phase_label_t out{};
153 check_status(siderust_moon_phase_label(c, &out), "moon::phase_label");
154 return static_cast<MoonPhaseLabel>(out);
155}
156
164inline std::vector<PhaseEvent> find_phase_events(const Period<TT, MJD> &window,
165 const SearchOptions &opts = {}) {
166 siderust_phase_event_t *ptr = nullptr;
167 uintptr_t count = 0;
168 check_status(siderust_find_phase_events(window.c_inner(), opts.to_c(), &ptr, &count),
169 "moon::find_phase_events");
170 return detail::phase_events_from_c(ptr, count);
171}
172
180inline std::vector<Period<TT, MJD>> illumination_above(const Period<TT, MJD> &window, double k_min,
181 const SearchOptions &opts = {}) {
182 tempoch_period_mjd_t *ptr = nullptr;
183 uintptr_t count = 0;
184 check_status(siderust_moon_illumination_above(window.c_inner(), k_min, opts.to_c(), &ptr, &count),
185 "moon::illumination_above");
186 return detail::illum_periods_from_c(ptr, count);
187}
188
196inline std::vector<Period<TT, MJD>> illumination_below(const Period<TT, MJD> &window, double k_max,
197 const SearchOptions &opts = {}) {
198 tempoch_period_mjd_t *ptr = nullptr;
199 uintptr_t count = 0;
200 check_status(siderust_moon_illumination_below(window.c_inner(), k_max, opts.to_c(), &ptr, &count),
201 "moon::illumination_below");
202 return detail::illum_periods_from_c(ptr, count);
203}
204
213inline std::vector<Period<TT, MJD>> illumination_range(const Period<TT, MJD> &window, double k_min,
214 double k_max,
215 const SearchOptions &opts = {}) {
216 tempoch_period_mjd_t *ptr = nullptr;
217 uintptr_t count = 0;
219 siderust_moon_illumination_range(window.c_inner(), k_min, k_max, opts.to_c(), &ptr, &count),
220 "moon::illumination_range");
221 return detail::illum_periods_from_c(ptr, count);
222}
223
224} // namespace moon
225
226// ============================================================================
227// Convenience helpers (pure C++, no FFI)
228// ============================================================================
229
233inline double illuminated_percent(const MoonPhaseGeometry &geom) {
234 return geom.illuminated_fraction * 100.0;
235}
236
240inline bool is_waxing(MoonPhaseLabel label) {
241 switch (label) {
245 return true;
246 default:
247 return false;
248 }
249}
250
254inline bool is_waning(MoonPhaseLabel label) {
255 switch (label) {
259 return true;
260 default:
261 return false;
262 }
263}
264
265// ============================================================================
266// Stream operators
267// ============================================================================
268
272inline std::ostream &operator<<(std::ostream &os, PhaseKind kind) {
273 switch (kind) {
275 return os << "new moon";
277 return os << "first quarter";
279 return os << "full moon";
281 return os << "last quarter";
282 }
283 return os << "unknown";
284}
285
289inline std::ostream &operator<<(std::ostream &os, MoonPhaseLabel label) {
290 switch (label) {
292 return os << "new moon";
294 return os << "waxing crescent";
296 return os << "first quarter";
298 return os << "waxing gibbous";
300 return os << "full moon";
302 return os << "waning gibbous";
304 return os << "last quarter";
306 return os << "waning crescent";
307 }
308 return os << "unknown";
309}
310
311} // namespace siderust
Altitude computations for Sun, Moon, stars, and arbitrary ICRS directions.
Coordinate module umbrella.
Error handling and utility base for the siderust C++ wrapper.
std::vector< PhaseEvent > phase_events_from_c(siderust_phase_event_t *ptr, uintptr_t count)
std::vector< Period< TT, MJD > > illum_periods_from_c(tempoch_period_mjd_t *ptr, uintptr_t count)
MoonPhaseGeometry phase_topocentric(const Time< TT, JD > &jd, const Geodetic &site)
Compute topocentric Moon phase geometry at a Julian Date.
std::vector< PhaseEvent > find_phase_events(const Period< TT, MJD > &window, const SearchOptions &opts={})
Find principal phase events (new moon, quarters, full moon) in a window.
std::vector< Period< TT, MJD > > illumination_above(const Period< TT, MJD > &window, double k_min, const SearchOptions &opts={})
Find periods when illuminated fraction is ≥ k_min.
MoonPhaseLabel phase_label(const MoonPhaseGeometry &geom)
Determine the descriptive phase label for a given geometry.
MoonPhaseGeometry phase_geocentric(const Time< TT, JD > &jd)
Compute geocentric Moon phase geometry at a Julian Date.
std::vector< Period< TT, MJD > > illumination_below(const Period< TT, MJD > &window, double k_max, const SearchOptions &opts={})
Find periods when illuminated fraction is ≤ k_max.
std::vector< Period< TT, MJD > > illumination_range(const Period< TT, MJD > &window, double k_min, double k_max, const SearchOptions &opts={})
Find periods when illuminated fraction is within [k_min, k_max].
tempoch::EncodedTime< Scale, Format > Time
Definition time.hpp:36
void check_status(siderust_status_t status, const char *operation)
Definition ffi_core.hpp:111
std::ostream & operator<<(std::ostream &os, AzimuthExtremumKind kind)
Stream operator for AzimuthExtremumKind.
Definition azimuth.hpp:395
tempoch::Period< Time< Scale, Format > > Period
Definition time.hpp:37
bool is_waning(MoonPhaseLabel label)
Check if a phase label describes a waning moon.
bool is_waxing(MoonPhaseLabel label)
Check if a phase label describes a waxing moon.
PhaseKind
Principal lunar phase kinds (new-moon quarter events).
double illuminated_percent(const MoonPhaseGeometry &geom)
Get the illuminated fraction as a percentage [0, 100].
MoonPhaseLabel
Descriptive moon phase labels (8 canonical phases).
Geodetic position (WGS84 ellipsoid).
Definition geodetic.hpp:29
siderust_geodetic_t to_c() const
Convert to C FFI struct.
Definition geodetic.hpp:44
Geometric description of the Moon's phase at a point in time.
double illuminated_fraction
Illuminated disc fraction in [0, 1].
qtty::Radian elongation
Sun–Moon elongation.
bool waxing
True when the Moon is waxing.
qtty::Radian phase_angle
Phase angle in [0, π].
static MoonPhaseGeometry from_c(const siderust_moon_phase_geometry_t &c)
A principal lunar phase event (new moon, first quarter, etc.).
Time< TT, MJD > time
Epoch of the event (Time<TT, MJD>).
static PhaseEvent from_c(const siderust_phase_event_t &c)
PhaseKind kind
Which principal phase occurred.
Options for altitude search algorithms.
Definition altitude.hpp:58
Public siderust time tags and typed time/period aliases.