siderust-cpp
Header-only C++ wrapper for siderust
Loading...
Searching...
No Matches
altitude.hpp
Go to the documentation of this file.
1#pragma once
2
11#include "bodies.hpp"
12#include "coordinates.hpp"
13#include "ffi_core.hpp"
14#include "time.hpp"
15#include <vector>
16
17namespace siderust {
18
19// ============================================================================
20// Event types
21// ============================================================================
22
29
30 static CrossingEvent from_c(const siderust_crossing_event_t& c) {
31 return {MJD(c.mjd), static_cast<CrossingDirection>(c.direction)};
32 }
33};
34
40 qtty::Degree altitude;
42
43 static CulminationEvent from_c(const siderust_culmination_event_t& c) {
44 return {MJD(c.mjd), qtty::Degree(c.altitude_deg), static_cast<CulminationKind>(c.kind)};
45 }
46};
47
48// ============================================================================
49// SearchOptions
50// ============================================================================
51
56 double time_tolerance_days = 1e-9;
57 double scan_step_days = 0.0;
58 bool has_scan_step = false;
59
60 SearchOptions() = default;
61
64 scan_step_days = step;
65 has_scan_step = true;
66 return *this;
67 }
68
72 return *this;
73 }
74
75 siderust_search_opts_t to_c() const {
77 }
78};
79
80// ============================================================================
81// Internal helpers
82// ============================================================================
83namespace detail {
84
85inline std::vector<Period> periods_from_c(tempoch_period_mjd_t* ptr, uintptr_t count) {
86 std::vector<Period> result;
87 result.reserve(count);
88 for (uintptr_t i = 0; i < count; ++i) {
89 result.push_back(Period::from_c(ptr[i]));
90 }
91 siderust_periods_free(ptr, count);
92 return result;
93}
94
95inline std::vector<CrossingEvent> crossings_from_c(siderust_crossing_event_t* ptr, uintptr_t count) {
96 std::vector<CrossingEvent> result;
97 result.reserve(count);
98 for (uintptr_t i = 0; i < count; ++i) {
99 result.push_back(CrossingEvent::from_c(ptr[i]));
100 }
101 siderust_crossings_free(ptr, count);
102 return result;
103}
104
105inline std::vector<CulminationEvent> culminations_from_c(siderust_culmination_event_t* ptr, uintptr_t count) {
106 std::vector<CulminationEvent> result;
107 result.reserve(count);
108 for (uintptr_t i = 0; i < count; ++i) {
109 result.push_back(CulminationEvent::from_c(ptr[i]));
110 }
111 siderust_culminations_free(ptr, count);
112 return result;
113}
114
115} // namespace detail
116
117// ============================================================================
118// Sun altitude
119// ============================================================================
120
121namespace sun {
122
126inline qtty::Radian altitude_at(const Geodetic& obs, const MJD& mjd) {
127 double out;
128 check_status(siderust_sun_altitude_at(obs.to_c(), mjd.value(), &out),
129 "sun::altitude_at");
130 return qtty::Radian(out);
131}
132
136inline std::vector<Period> above_threshold(
137 const Geodetic& obs, const Period& window,
138 qtty::Degree threshold, const SearchOptions& opts = {}) {
139 tempoch_period_mjd_t* ptr = nullptr;
140 uintptr_t count = 0;
141 check_status(siderust_sun_above_threshold(
142 obs.to_c(), window.c_inner(), threshold.value(),
143 opts.to_c(), &ptr, &count),
144 "sun::above_threshold");
145 return detail::periods_from_c(ptr, count);
146}
147
151inline std::vector<Period> above_threshold(
152 const Geodetic& obs, const MJD& start, const MJD& end,
153 qtty::Degree threshold, const SearchOptions& opts = {}) {
154 return above_threshold(obs, Period(start, end), threshold, opts);
155}
156
160inline std::vector<Period> below_threshold(
161 const Geodetic& obs, const Period& window,
162 qtty::Degree threshold, const SearchOptions& opts = {}) {
163 tempoch_period_mjd_t* ptr = nullptr;
164 uintptr_t count = 0;
165 check_status(siderust_sun_below_threshold(
166 obs.to_c(), window.c_inner(), threshold.value(),
167 opts.to_c(), &ptr, &count),
168 "sun::below_threshold");
169 return detail::periods_from_c(ptr, count);
170}
171
175inline std::vector<Period> below_threshold(
176 const Geodetic& obs, const MJD& start, const MJD& end,
177 qtty::Degree threshold, const SearchOptions& opts = {}) {
178 return below_threshold(obs, Period(start, end), threshold, opts);
179}
180
184inline std::vector<CrossingEvent> crossings(
185 const Geodetic& obs, const Period& window,
186 qtty::Degree threshold, const SearchOptions& opts = {}) {
187 siderust_crossing_event_t* ptr = nullptr;
188 uintptr_t count = 0;
189 check_status(siderust_sun_crossings(
190 obs.to_c(), window.c_inner(), threshold.value(),
191 opts.to_c(), &ptr, &count),
192 "sun::crossings");
193 return detail::crossings_from_c(ptr, count);
194}
195
199inline std::vector<CrossingEvent> crossings(
200 const Geodetic& obs, const MJD& start, const MJD& end,
201 qtty::Degree threshold, const SearchOptions& opts = {}) {
202 return crossings(obs, Period(start, end), threshold, opts);
203}
204
208inline std::vector<CulminationEvent> culminations(
209 const Geodetic& obs, const Period& window,
210 const SearchOptions& opts = {}) {
211 siderust_culmination_event_t* ptr = nullptr;
212 uintptr_t count = 0;
213 check_status(siderust_sun_culminations(
214 obs.to_c(), window.c_inner(),
215 opts.to_c(), &ptr, &count),
216 "sun::culminations");
217 return detail::culminations_from_c(ptr, count);
218}
219
223inline std::vector<CulminationEvent> culminations(
224 const Geodetic& obs, const MJD& start, const MJD& end,
225 const SearchOptions& opts = {}) {
226 return culminations(obs, Period(start, end), opts);
227}
228
232inline std::vector<Period> altitude_periods(
233 const Geodetic& obs, const Period& window,
234 qtty::Degree min_alt, qtty::Degree max_alt) {
235 siderust_altitude_query_t q = {obs.to_c(), window.start().value(), window.end().value(),
236 min_alt.value(), max_alt.value()};
237 tempoch_period_mjd_t* ptr = nullptr;
238 uintptr_t count = 0;
239 check_status(siderust_sun_altitude_periods(q, &ptr, &count),
240 "sun::altitude_periods");
241 return detail::periods_from_c(ptr, count);
242}
243
247inline std::vector<Period> altitude_periods(
248 const Geodetic& obs, const MJD& start, const MJD& end,
249 qtty::Degree min_alt, qtty::Degree max_alt) {
250 siderust_altitude_query_t q = {obs.to_c(), start.value(), end.value(),
251 min_alt.value(), max_alt.value()};
252 tempoch_period_mjd_t* ptr = nullptr;
253 uintptr_t count = 0;
254 check_status(siderust_sun_altitude_periods(q, &ptr, &count),
255 "sun::altitude_periods");
256 return detail::periods_from_c(ptr, count);
257}
258
259} // namespace sun
260
261// ============================================================================
262// Moon altitude
263// ============================================================================
264
265namespace moon {
266
270inline qtty::Radian altitude_at(const Geodetic& obs, const MJD& mjd) {
271 double out;
272 check_status(siderust_moon_altitude_at(obs.to_c(), mjd.value(), &out),
273 "moon::altitude_at");
274 return qtty::Radian(out);
275}
276
280inline std::vector<Period> above_threshold(
281 const Geodetic& obs, const Period& window,
282 qtty::Degree threshold, const SearchOptions& opts = {}) {
283 tempoch_period_mjd_t* ptr = nullptr;
284 uintptr_t count = 0;
285 check_status(siderust_moon_above_threshold(
286 obs.to_c(), window.c_inner(), threshold.value(),
287 opts.to_c(), &ptr, &count),
288 "moon::above_threshold");
289 return detail::periods_from_c(ptr, count);
290}
291
295inline std::vector<Period> above_threshold(
296 const Geodetic& obs, const MJD& start, const MJD& end,
297 qtty::Degree threshold, const SearchOptions& opts = {}) {
298 return above_threshold(obs, Period(start, end), threshold, opts);
299}
300
304inline std::vector<Period> below_threshold(
305 const Geodetic& obs, const Period& window,
306 qtty::Degree threshold, const SearchOptions& opts = {}) {
307 tempoch_period_mjd_t* ptr = nullptr;
308 uintptr_t count = 0;
309 check_status(siderust_moon_below_threshold(
310 obs.to_c(), window.c_inner(), threshold.value(),
311 opts.to_c(), &ptr, &count),
312 "moon::below_threshold");
313 return detail::periods_from_c(ptr, count);
314}
315
319inline std::vector<Period> below_threshold(
320 const Geodetic& obs, const MJD& start, const MJD& end,
321 qtty::Degree threshold, const SearchOptions& opts = {}) {
322 return below_threshold(obs, Period(start, end), threshold, opts);
323}
324
328inline std::vector<CrossingEvent> crossings(
329 const Geodetic& obs, const Period& window,
330 qtty::Degree threshold, const SearchOptions& opts = {}) {
331 siderust_crossing_event_t* ptr = nullptr;
332 uintptr_t count = 0;
333 check_status(siderust_moon_crossings(
334 obs.to_c(), window.c_inner(), threshold.value(),
335 opts.to_c(), &ptr, &count),
336 "moon::crossings");
337 return detail::crossings_from_c(ptr, count);
338}
339
343inline std::vector<CrossingEvent> crossings(
344 const Geodetic& obs, const MJD& start, const MJD& end,
345 qtty::Degree threshold, const SearchOptions& opts = {}) {
346 return crossings(obs, Period(start, end), threshold, opts);
347}
348
352inline std::vector<CulminationEvent> culminations(
353 const Geodetic& obs, const Period& window,
354 const SearchOptions& opts = {}) {
355 siderust_culmination_event_t* ptr = nullptr;
356 uintptr_t count = 0;
357 check_status(siderust_moon_culminations(
358 obs.to_c(), window.c_inner(),
359 opts.to_c(), &ptr, &count),
360 "moon::culminations");
361 return detail::culminations_from_c(ptr, count);
362}
363
367inline std::vector<CulminationEvent> culminations(
368 const Geodetic& obs, const MJD& start, const MJD& end,
369 const SearchOptions& opts = {}) {
370 return culminations(obs, Period(start, end), opts);
371}
372
376inline std::vector<Period> altitude_periods(
377 const Geodetic& obs, const Period& window,
378 qtty::Degree min_alt, qtty::Degree max_alt) {
379 siderust_altitude_query_t q = {obs.to_c(), window.start().value(), window.end().value(),
380 min_alt.value(), max_alt.value()};
381 tempoch_period_mjd_t* ptr = nullptr;
382 uintptr_t count = 0;
383 check_status(siderust_moon_altitude_periods(q, &ptr, &count),
384 "moon::altitude_periods");
385 return detail::periods_from_c(ptr, count);
386}
387
391inline std::vector<Period> altitude_periods(
392 const Geodetic& obs, const MJD& start, const MJD& end,
393 qtty::Degree min_alt, qtty::Degree max_alt) {
394 siderust_altitude_query_t q = {obs.to_c(), start.value(), end.value(),
395 min_alt.value(), max_alt.value()};
396 tempoch_period_mjd_t* ptr = nullptr;
397 uintptr_t count = 0;
398 check_status(siderust_moon_altitude_periods(q, &ptr, &count),
399 "moon::altitude_periods");
400 return detail::periods_from_c(ptr, count);
401}
402
403} // namespace moon
404
405// ============================================================================
406// Star altitude
407// ============================================================================
408
409namespace star_altitude {
410
414inline qtty::Radian altitude_at(const Star& s, const Geodetic& obs, const MJD& mjd) {
415 double out;
416 check_status(siderust_star_altitude_at(
417 s.c_handle(), obs.to_c(), mjd.value(), &out),
418 "star_altitude::altitude_at");
419 return qtty::Radian(out);
420}
421
425inline std::vector<Period> above_threshold(
426 const Star& s, const Geodetic& obs, const Period& window,
427 qtty::Degree threshold, const SearchOptions& opts = {}) {
428 tempoch_period_mjd_t* ptr = nullptr;
429 uintptr_t count = 0;
430 check_status(siderust_star_above_threshold(
431 s.c_handle(), obs.to_c(), window.c_inner(), threshold.value(),
432 opts.to_c(), &ptr, &count),
433 "star_altitude::above_threshold");
434 return detail::periods_from_c(ptr, count);
435}
436
440inline std::vector<Period> above_threshold(
441 const Star& s, const Geodetic& obs, const MJD& start, const MJD& end,
442 qtty::Degree threshold, const SearchOptions& opts = {}) {
443 return above_threshold(s, obs, Period(start, end), threshold, opts);
444}
445
449inline std::vector<Period> below_threshold(
450 const Star& s, const Geodetic& obs, const Period& window,
451 qtty::Degree threshold, const SearchOptions& opts = {}) {
452 tempoch_period_mjd_t* ptr = nullptr;
453 uintptr_t count = 0;
454 check_status(siderust_star_below_threshold(
455 s.c_handle(), obs.to_c(), window.c_inner(), threshold.value(),
456 opts.to_c(), &ptr, &count),
457 "star_altitude::below_threshold");
458 return detail::periods_from_c(ptr, count);
459}
460
464inline std::vector<Period> below_threshold(
465 const Star& s, const Geodetic& obs, const MJD& start, const MJD& end,
466 qtty::Degree threshold, const SearchOptions& opts = {}) {
467 return below_threshold(s, obs, Period(start, end), threshold, opts);
468}
469
473inline std::vector<CrossingEvent> crossings(
474 const Star& s, const Geodetic& obs, const Period& window,
475 qtty::Degree threshold, const SearchOptions& opts = {}) {
476 siderust_crossing_event_t* ptr = nullptr;
477 uintptr_t count = 0;
478 check_status(siderust_star_crossings(
479 s.c_handle(), obs.to_c(), window.c_inner(), threshold.value(),
480 opts.to_c(), &ptr, &count),
481 "star_altitude::crossings");
482 return detail::crossings_from_c(ptr, count);
483}
484
488inline std::vector<CrossingEvent> crossings(
489 const Star& s, const Geodetic& obs, const MJD& start, const MJD& end,
490 qtty::Degree threshold, const SearchOptions& opts = {}) {
491 return crossings(s, obs, Period(start, end), threshold, opts);
492}
493
497inline std::vector<CulminationEvent> culminations(
498 const Star& s, const Geodetic& obs, const Period& window,
499 const SearchOptions& opts = {}) {
500 siderust_culmination_event_t* ptr = nullptr;
501 uintptr_t count = 0;
502 check_status(siderust_star_culminations(
503 s.c_handle(), obs.to_c(), window.c_inner(),
504 opts.to_c(), &ptr, &count),
505 "star_altitude::culminations");
506 return detail::culminations_from_c(ptr, count);
507}
508
512inline std::vector<CulminationEvent> culminations(
513 const Star& s, const Geodetic& obs, const MJD& start, const MJD& end,
514 const SearchOptions& opts = {}) {
515 return culminations(s, obs, Period(start, end), opts);
516}
517
518} // namespace star_altitude
519
520// ============================================================================
521// ICRS direction altitude
522// ============================================================================
523
524namespace icrs_altitude {
525
529inline qtty::Radian altitude_at(const spherical::direction::ICRS& dir,
530 const Geodetic& obs, const MJD& mjd) {
531 double out;
532 check_status(siderust_icrs_altitude_at(
533 dir.to_c(), obs.to_c(), mjd.value(), &out),
534 "icrs_altitude::altitude_at");
535 return qtty::Radian(out);
536}
537
541inline qtty::Radian altitude_at(qtty::Degree ra, qtty::Degree dec,
542 const Geodetic& obs, const MJD& mjd) {
543 return altitude_at(spherical::direction::ICRS(ra, dec), obs, mjd);
544}
545
549inline std::vector<Period> above_threshold(
551 const Geodetic& obs, const Period& window,
552 qtty::Degree threshold, const SearchOptions& opts = {}) {
553 tempoch_period_mjd_t* ptr = nullptr;
554 uintptr_t count = 0;
555 check_status(siderust_icrs_above_threshold(
556 dir.to_c(), obs.to_c(), window.c_inner(),
557 threshold.value(), opts.to_c(), &ptr, &count),
558 "icrs_altitude::above_threshold");
559 return detail::periods_from_c(ptr, count);
560}
561
565inline std::vector<Period> above_threshold(
566 qtty::Degree ra, qtty::Degree dec,
567 const Geodetic& obs, const MJD& start, const MJD& end,
568 qtty::Degree threshold, const SearchOptions& opts = {}) {
569 return above_threshold(
571 obs,
572 Period(start, end),
573 threshold,
574 opts);
575}
576
580inline std::vector<Period> below_threshold(
582 const Geodetic& obs, const Period& window,
583 qtty::Degree threshold, const SearchOptions& opts = {}) {
584 tempoch_period_mjd_t* ptr = nullptr;
585 uintptr_t count = 0;
586 check_status(siderust_icrs_below_threshold(
587 dir.to_c(), obs.to_c(), window.c_inner(),
588 threshold.value(), opts.to_c(), &ptr, &count),
589 "icrs_altitude::below_threshold");
590 return detail::periods_from_c(ptr, count);
591}
592
596inline std::vector<Period> below_threshold(
597 qtty::Degree ra, qtty::Degree dec,
598 const Geodetic& obs, const MJD& start, const MJD& end,
599 qtty::Degree threshold, const SearchOptions& opts = {}) {
600 return below_threshold(
602 obs,
603 Period(start, end),
604 threshold,
605 opts);
606}
607
608} // namespace icrs_altitude
609
610} // namespace siderust
RAII Star handle, Planet value type, and catalog helpers.
RAII handle to a Star (opaque Rust object).
Definition bodies.hpp:158
const SiderustStar * c_handle() const
Access the raw C handle (for passing to altitude functions).
Definition bodies.hpp:188
Coordinate module umbrella.
Error handling and utility base for the siderust C++ wrapper.
std::vector< CrossingEvent > crossings_from_c(siderust_crossing_event_t *ptr, uintptr_t count)
Definition altitude.hpp:95
std::vector< Period > periods_from_c(tempoch_period_mjd_t *ptr, uintptr_t count)
Definition altitude.hpp:85
std::vector< CulminationEvent > culminations_from_c(siderust_culmination_event_t *ptr, uintptr_t count)
Definition altitude.hpp:105
std::vector< Period > below_threshold(const spherical::direction::ICRS &dir, const Geodetic &obs, const Period &window, qtty::Degree threshold, const SearchOptions &opts={})
Find periods when a fixed ICRS direction is below a threshold.
Definition altitude.hpp:580
qtty::Radian altitude_at(const spherical::direction::ICRS &dir, const Geodetic &obs, const MJD &mjd)
Compute altitude (radians) for a fixed ICRS direction.
Definition altitude.hpp:529
std::vector< Period > above_threshold(const spherical::direction::ICRS &dir, const Geodetic &obs, const Period &window, qtty::Degree threshold, const SearchOptions &opts={})
Find periods when a fixed ICRS direction is above a threshold.
Definition altitude.hpp:549
std::vector< Period > altitude_periods(const Geodetic &obs, const Period &window, qtty::Degree min_alt, qtty::Degree max_alt)
Find periods when the Moon's altitude is within [min, max].
Definition altitude.hpp:376
std::vector< CulminationEvent > culminations(const Geodetic &obs, const Period &window, const SearchOptions &opts={})
Find culmination events for the Moon.
Definition altitude.hpp:352
std::vector< CrossingEvent > crossings(const Geodetic &obs, const Period &window, qtty::Degree threshold, const SearchOptions &opts={})
Find threshold-crossing events for the Moon.
Definition altitude.hpp:328
std::vector< Period > below_threshold(const Geodetic &obs, const Period &window, qtty::Degree threshold, const SearchOptions &opts={})
Find periods when the Moon is below a threshold altitude.
Definition altitude.hpp:304
std::vector< Period > above_threshold(const Geodetic &obs, const Period &window, qtty::Degree threshold, const SearchOptions &opts={})
Find periods when the Moon is above a threshold altitude.
Definition altitude.hpp:280
qtty::Radian altitude_at(const Geodetic &obs, const MJD &mjd)
Compute the Moon's altitude (radians) at a given MJD instant.
Definition altitude.hpp:270
std::vector< Period > above_threshold(const Star &s, const Geodetic &obs, const Period &window, qtty::Degree threshold, const SearchOptions &opts={})
Find periods when a star is above a threshold altitude.
Definition altitude.hpp:425
qtty::Radian altitude_at(const Star &s, const Geodetic &obs, const MJD &mjd)
Compute a star's altitude (radians) at a given MJD instant.
Definition altitude.hpp:414
std::vector< Period > below_threshold(const Star &s, const Geodetic &obs, const Period &window, qtty::Degree threshold, const SearchOptions &opts={})
Find periods when a star is below a threshold altitude.
Definition altitude.hpp:449
std::vector< CulminationEvent > culminations(const Star &s, const Geodetic &obs, const Period &window, const SearchOptions &opts={})
Find culmination events for a star.
Definition altitude.hpp:497
std::vector< CrossingEvent > crossings(const Star &s, const Geodetic &obs, const Period &window, qtty::Degree threshold, const SearchOptions &opts={})
Find threshold-crossing events for a star.
Definition altitude.hpp:473
std::vector< CrossingEvent > crossings(const Geodetic &obs, const Period &window, qtty::Degree threshold, const SearchOptions &opts={})
Find threshold-crossing events for the Sun.
Definition altitude.hpp:184
std::vector< Period > altitude_periods(const Geodetic &obs, const Period &window, qtty::Degree min_alt, qtty::Degree max_alt)
Find periods when the Sun's altitude is within [min, max].
Definition altitude.hpp:232
std::vector< Period > below_threshold(const Geodetic &obs, const Period &window, qtty::Degree threshold, const SearchOptions &opts={})
Find periods when the Sun is below a threshold altitude.
Definition altitude.hpp:160
qtty::Radian altitude_at(const Geodetic &obs, const MJD &mjd)
Compute the Sun's altitude (radians) at a given MJD instant.
Definition altitude.hpp:126
std::vector< Period > above_threshold(const Geodetic &obs, const Period &window, qtty::Degree threshold, const SearchOptions &opts={})
Find periods when the Sun is above a threshold altitude.
Definition altitude.hpp:136
std::vector< CulminationEvent > culminations(const Geodetic &obs, const Period &window, const SearchOptions &opts={})
Find culmination events for the Sun.
Definition altitude.hpp:208
tempoch::Period Period
Definition time.hpp:19
void check_status(siderust_status_t status, const char *operation)
Definition ffi_core.hpp:81
tempoch::MJD MJD
Definition time.hpp:18
A threshold-crossing event (rising or setting).
Definition altitude.hpp:26
CrossingDirection direction
Definition altitude.hpp:28
static CrossingEvent from_c(const siderust_crossing_event_t &c)
Definition altitude.hpp:30
A culmination (local altitude extremum) event.
Definition altitude.hpp:38
static CulminationEvent from_c(const siderust_culmination_event_t &c)
Definition altitude.hpp:43
Geodetic position (WGS84 ellipsoid).
Definition geodetic.hpp:28
siderust_geodetic_t to_c() const
Convert to C FFI struct.
Definition geodetic.hpp:45
Options for altitude search algorithms.
Definition altitude.hpp:55
siderust_search_opts_t to_c() const
Definition altitude.hpp:75
SearchOptions & with_scan_step(double step)
Set a custom scan step.
Definition altitude.hpp:63
SearchOptions & with_tolerance(double tol)
Set time tolerance.
Definition altitude.hpp:70
A direction on the celestial sphere, compile-time tagged by frame.
Definition spherical.hpp:36
siderust_spherical_dir_t to_c() const
Re-exports tempoch C++ types into the siderust namespace.