siderust-cpp 0.8.0
Header-only C++ wrapper for siderust
Loading...
Searching...
No Matches
azimuth.hpp
Go to the documentation of this file.
1#pragma once
2
21#include "altitude.hpp"
22#include "bodies.hpp"
23#include "coordinates.hpp"
24#include "ffi_core.hpp"
25#include "time.hpp"
26#include <ostream>
27#include <vector>
28
29namespace siderust {
30
31// ============================================================================
32// Azimuth event types
33// ============================================================================
34
38enum class AzimuthExtremumKind : int32_t {
39 Max = 0,
40 Min = 1,
41};
42
49
50 static AzimuthCrossingEvent from_c(const siderust_azimuth_crossing_event_t &c) {
51 return {Time<TT, MJD>(c.mjd), static_cast<CrossingDirection>(c.direction)};
52 }
53};
54
60 qtty::Degree azimuth;
62
63 static AzimuthExtremum from_c(const siderust_azimuth_extremum_t &c) {
64 return {Time<TT, MJD>(c.mjd), qtty::Degree(c.azimuth_deg),
65 static_cast<AzimuthExtremumKind>(c.kind)};
66 }
67};
68
69// ============================================================================
70// Internal helpers
71// ============================================================================
72namespace detail {
73
74inline std::vector<AzimuthCrossingEvent> az_crossings_from_c(siderust_azimuth_crossing_event_t *ptr,
75 uintptr_t count) {
76 std::vector<AzimuthCrossingEvent> result;
77 result.reserve(count);
78 for (uintptr_t i = 0; i < count; ++i) {
79 result.push_back(AzimuthCrossingEvent::from_c(ptr[i]));
80 }
81 siderust_azimuth_crossings_free(ptr, count);
82 return result;
83}
84
85inline std::vector<AzimuthExtremum> az_extrema_from_c(siderust_azimuth_extremum_t *ptr,
86 uintptr_t count) {
87 std::vector<AzimuthExtremum> result;
88 result.reserve(count);
89 for (uintptr_t i = 0; i < count; ++i) {
90 result.push_back(AzimuthExtremum::from_c(ptr[i]));
91 }
92 siderust_azimuth_extrema_free(ptr, count);
93 return result;
94}
95
96} // namespace detail
97
98// ============================================================================
99// Sun azimuth
100// ============================================================================
101
102namespace sun {
103
108inline qtty::Degree azimuth_at(const Geodetic &obs, const Time<TT, MJD> &mjd) {
109 double out;
110 check_status(siderust_azimuth_at(detail::make_body_subject(SIDERUST_BODY_SUN), obs.to_c(),
111 mjd.value(), &out),
112 "sun::azimuth_at");
113 return qtty::Degree(out);
114}
115
119inline std::vector<AzimuthCrossingEvent> azimuth_crossings(const Geodetic &obs,
120 const Period<TT, MJD> &window,
121 qtty::Degree bearing,
122 const SearchOptions &opts = {}) {
123 siderust_azimuth_crossing_event_t *ptr = nullptr;
124 uintptr_t count = 0;
125 check_status(siderust_azimuth_crossings(detail::make_body_subject(SIDERUST_BODY_SUN), obs.to_c(),
126 window.c_inner(), bearing.value(), opts.to_c(), &ptr,
127 &count),
128 "sun::azimuth_crossings");
129 return detail::az_crossings_from_c(ptr, count);
130}
131
135inline std::vector<AzimuthExtremum> azimuth_extrema(const Geodetic &obs,
136 const Period<TT, MJD> &window,
137 const SearchOptions &opts = {}) {
138 siderust_azimuth_extremum_t *ptr = nullptr;
139 uintptr_t count = 0;
140 check_status(siderust_azimuth_extrema(detail::make_body_subject(SIDERUST_BODY_SUN), obs.to_c(),
141 window.c_inner(), opts.to_c(), &ptr, &count),
142 "sun::azimuth_extrema");
143 return detail::az_extrema_from_c(ptr, count);
144}
145
150inline std::vector<Period<TT, MJD>>
151in_azimuth_range(const Geodetic &obs, const Period<TT, MJD> &window, qtty::Degree min_bearing,
152 qtty::Degree max_bearing, const SearchOptions &opts = {}) {
153 tempoch_period_mjd_t *ptr = nullptr;
154 uintptr_t count = 0;
155 check_status(siderust_in_azimuth_range(detail::make_body_subject(SIDERUST_BODY_SUN), obs.to_c(),
156 window.c_inner(), min_bearing.value(), max_bearing.value(),
157 opts.to_c(), &ptr, &count),
158 "sun::in_azimuth_range");
159 return detail::periods_from_c(ptr, count);
160}
161
166inline std::vector<Period<TT, MJD>>
167outside_azimuth_range(const Geodetic &obs, const Period<TT, MJD> &window, qtty::Degree min_bearing,
168 qtty::Degree max_bearing, const SearchOptions &opts = {}) {
169 tempoch_period_mjd_t *ptr = nullptr;
170 uintptr_t count = 0;
171 check_status(siderust_outside_azimuth_range(detail::make_body_subject(SIDERUST_BODY_SUN),
172 obs.to_c(), window.c_inner(), min_bearing.value(),
173 max_bearing.value(), opts.to_c(), &ptr, &count),
174 "sun::outside_azimuth_range");
175 return detail::periods_from_c(ptr, count);
176}
177
178} // namespace sun
179
180// ============================================================================
181// Moon azimuth
182// ============================================================================
183
184namespace moon {
185
190inline qtty::Degree azimuth_at(const Geodetic &obs, const Time<TT, MJD> &mjd) {
191 double out;
192 check_status(siderust_azimuth_at(detail::make_body_subject(SIDERUST_BODY_MOON), obs.to_c(),
193 mjd.value(), &out),
194 "moon::azimuth_at");
195 return qtty::Degree(out);
196}
197
201inline std::vector<AzimuthCrossingEvent> azimuth_crossings(const Geodetic &obs,
202 const Period<TT, MJD> &window,
203 qtty::Degree bearing,
204 const SearchOptions &opts = {}) {
205 siderust_azimuth_crossing_event_t *ptr = nullptr;
206 uintptr_t count = 0;
207 check_status(siderust_azimuth_crossings(detail::make_body_subject(SIDERUST_BODY_MOON), obs.to_c(),
208 window.c_inner(), bearing.value(), opts.to_c(), &ptr,
209 &count),
210 "moon::azimuth_crossings");
211 return detail::az_crossings_from_c(ptr, count);
212}
213
217inline std::vector<AzimuthExtremum> azimuth_extrema(const Geodetic &obs,
218 const Period<TT, MJD> &window,
219 const SearchOptions &opts = {}) {
220 siderust_azimuth_extremum_t *ptr = nullptr;
221 uintptr_t count = 0;
222 check_status(siderust_azimuth_extrema(detail::make_body_subject(SIDERUST_BODY_MOON), obs.to_c(),
223 window.c_inner(), opts.to_c(), &ptr, &count),
224 "moon::azimuth_extrema");
225 return detail::az_extrema_from_c(ptr, count);
226}
227
232inline std::vector<Period<TT, MJD>>
233in_azimuth_range(const Geodetic &obs, const Period<TT, MJD> &window, qtty::Degree min_bearing,
234 qtty::Degree max_bearing, const SearchOptions &opts = {}) {
235 tempoch_period_mjd_t *ptr = nullptr;
236 uintptr_t count = 0;
237 check_status(siderust_in_azimuth_range(detail::make_body_subject(SIDERUST_BODY_MOON), obs.to_c(),
238 window.c_inner(), min_bearing.value(), max_bearing.value(),
239 opts.to_c(), &ptr, &count),
240 "moon::in_azimuth_range");
241 return detail::periods_from_c(ptr, count);
242}
243
248inline std::vector<Period<TT, MJD>>
249outside_azimuth_range(const Geodetic &obs, const Period<TT, MJD> &window, qtty::Degree min_bearing,
250 qtty::Degree max_bearing, const SearchOptions &opts = {}) {
251 tempoch_period_mjd_t *ptr = nullptr;
252 uintptr_t count = 0;
253 check_status(siderust_outside_azimuth_range(detail::make_body_subject(SIDERUST_BODY_MOON),
254 obs.to_c(), window.c_inner(), min_bearing.value(),
255 max_bearing.value(), opts.to_c(), &ptr, &count),
256 "moon::outside_azimuth_range");
257 return detail::periods_from_c(ptr, count);
258}
259
260} // namespace moon
261
262// ============================================================================
263// Star azimuth
264// ============================================================================
265
266namespace star_altitude {
267
272inline qtty::Degree azimuth_at(const Star &s, const Geodetic &obs, const Time<TT, MJD> &mjd) {
273 double out;
275 siderust_azimuth_at(detail::make_star_subject(s.c_handle()), obs.to_c(), mjd.value(), &out),
276 "star_altitude::azimuth_at");
277 return qtty::Degree(out);
278}
279
283inline std::vector<AzimuthCrossingEvent> azimuth_crossings(const Star &s, const Geodetic &obs,
284 const Period<TT, MJD> &window,
285 qtty::Degree bearing,
286 const SearchOptions &opts = {}) {
287 siderust_azimuth_crossing_event_t *ptr = nullptr;
288 uintptr_t count = 0;
289 check_status(siderust_azimuth_crossings(detail::make_star_subject(s.c_handle()), obs.to_c(),
290 window.c_inner(), bearing.value(), opts.to_c(), &ptr,
291 &count),
292 "star_altitude::azimuth_crossings");
293 return detail::az_crossings_from_c(ptr, count);
294}
295
299inline std::vector<Period<TT, MJD>> in_azimuth_range(const Star &s, const Geodetic &obs,
300 const Period<TT, MJD> &window,
301 qtty::Degree min_bearing,
302 qtty::Degree max_bearing,
303 const SearchOptions &opts = {}) {
304 tempoch_period_mjd_t *ptr = nullptr;
305 uintptr_t count = 0;
306 check_status(siderust_in_azimuth_range(detail::make_star_subject(s.c_handle()), obs.to_c(),
307 window.c_inner(), min_bearing.value(), max_bearing.value(),
308 opts.to_c(), &ptr, &count),
309 "star_altitude::in_azimuth_range");
310 return detail::periods_from_c(ptr, count);
311}
312
316inline std::vector<Period<TT, MJD>> outside_azimuth_range(const Star &s, const Geodetic &obs,
317 const Period<TT, MJD> &window,
318 qtty::Degree min_bearing,
319 qtty::Degree max_bearing,
320 const SearchOptions &opts = {}) {
321 tempoch_period_mjd_t *ptr = nullptr;
322 uintptr_t count = 0;
323 check_status(siderust_outside_azimuth_range(detail::make_star_subject(s.c_handle()), obs.to_c(),
324 window.c_inner(), min_bearing.value(),
325 max_bearing.value(), opts.to_c(), &ptr, &count),
326 "star_altitude::outside_azimuth_range");
327 return detail::periods_from_c(ptr, count);
328}
329
330} // namespace star_altitude
331
332// ============================================================================
333// ICRS direction azimuth
334// ============================================================================
335
336namespace icrs_altitude {
337
341inline qtty::Degree azimuth_at(const spherical::direction::ICRS &dir, const Geodetic &obs,
342 const Time<TT, MJD> &mjd) {
343 double out;
345 siderust_azimuth_at(detail::make_icrs_subject(dir.to_c()), obs.to_c(), mjd.value(), &out),
346 "icrs_altitude::azimuth_at");
347 return qtty::Degree(out);
348}
349
353inline qtty::Degree azimuth_at(qtty::Degree ra, qtty::Degree dec, const Geodetic &obs,
354 const Time<TT, MJD> &mjd) {
355 return azimuth_at(spherical::direction::ICRS(ra, dec), obs, mjd);
356}
357
361inline std::vector<AzimuthCrossingEvent> azimuth_crossings(const spherical::direction::ICRS &dir,
362 const Geodetic &obs,
363 const Period<TT, MJD> &window,
364 qtty::Degree bearing,
365 const SearchOptions &opts = {}) {
366 siderust_azimuth_crossing_event_t *ptr = nullptr;
367 uintptr_t count = 0;
368 check_status(siderust_azimuth_crossings(detail::make_icrs_subject(dir.to_c()), obs.to_c(),
369 window.c_inner(), bearing.value(), opts.to_c(), &ptr,
370 &count),
371 "icrs_altitude::azimuth_crossings");
372 return detail::az_crossings_from_c(ptr, count);
373}
374
378inline std::vector<AzimuthCrossingEvent> azimuth_crossings(qtty::Degree ra, qtty::Degree dec,
379 const Geodetic &obs,
380 const Period<TT, MJD> &window,
381 qtty::Degree bearing,
382 const SearchOptions &opts = {}) {
383 return azimuth_crossings(spherical::direction::ICRS(ra, dec), obs, window, bearing, opts);
384}
385
386} // namespace icrs_altitude
387
388// ============================================================================
389// Stream operators
390// ============================================================================
391
395inline std::ostream &operator<<(std::ostream &os, AzimuthExtremumKind kind) {
396 switch (kind) {
398 return os << "max";
400 return os << "min";
401 }
402 return os << "unknown";
403}
404
405} // namespace siderust
Altitude computations for Sun, Moon, stars, and arbitrary ICRS directions.
RAII Star handle, Planet value type, and catalog helpers.
RAII handle to a Star (opaque Rust object).
Definition bodies.hpp:176
const SiderustStar * c_handle() const
Access the raw C handle (for passing to altitude functions).
Definition bodies.hpp:206
Coordinate module umbrella.
Error handling and utility base for the siderust C++ wrapper.
std::vector< AzimuthExtremum > az_extrema_from_c(siderust_azimuth_extremum_t *ptr, uintptr_t count)
Definition azimuth.hpp:85
siderust_subject_t make_star_subject(const SiderustStar *h)
Build a siderust_subject_t for a star, borrowing the handle.
Definition ffi_core.hpp:266
siderust_subject_t make_body_subject(SiderustBody b)
Build a siderust_subject_t for a solar-system body.
Definition ffi_core.hpp:258
std::vector< AzimuthCrossingEvent > az_crossings_from_c(siderust_azimuth_crossing_event_t *ptr, uintptr_t count)
Definition azimuth.hpp:74
siderust_subject_t make_icrs_subject(const siderust_spherical_dir_t &dir)
Build a siderust_subject_t for a fixed ICRS direction.
Definition ffi_core.hpp:274
std::vector< Period< TT, MJD > > periods_from_c(tempoch_period_mjd_t *ptr, uintptr_t count)
Definition altitude.hpp:77
qtty::Degree azimuth_at(const spherical::direction::ICRS &dir, const Geodetic &obs, const Time< TT, MJD > &mjd)
Compute azimuth (degrees, N-clockwise) for a fixed ICRS direction.
Definition azimuth.hpp:341
std::vector< AzimuthCrossingEvent > azimuth_crossings(const spherical::direction::ICRS &dir, const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree bearing, const SearchOptions &opts={})
Find epochs when an ICRS direction crosses a given azimuth bearing.
Definition azimuth.hpp:361
std::vector< AzimuthExtremum > azimuth_extrema(const Geodetic &obs, const Period< TT, MJD > &window, const SearchOptions &opts={})
Find azimuth extrema (northernmost / southernmost) for the Moon.
Definition azimuth.hpp:217
std::vector< AzimuthCrossingEvent > azimuth_crossings(const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree bearing, const SearchOptions &opts={})
Find epochs when the Moon crosses a given bearing.
Definition azimuth.hpp:201
std::vector< Period< TT, MJD > > outside_azimuth_range(const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree min_bearing, qtty::Degree max_bearing, const SearchOptions &opts={})
Find periods when the Moon's azimuth is outside [min_bearing, max_bearing].
Definition azimuth.hpp:249
std::vector< Period< TT, MJD > > in_azimuth_range(const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree min_bearing, qtty::Degree max_bearing, const SearchOptions &opts={})
Find periods when the Moon's azimuth is within [min_bearing, max_bearing].
Definition azimuth.hpp:233
qtty::Degree azimuth_at(const Geodetic &obs, const Time< TT, MJD > &mjd)
Compute the Moon's azimuth (degrees, N-clockwise) at a given Time<TT, MJD> instant.
Definition azimuth.hpp:190
std::vector< Period< TT, MJD > > outside_azimuth_range(const Star &s, const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree min_bearing, qtty::Degree max_bearing, const SearchOptions &opts={})
Find periods when a star's azimuth is outside [min, max] (degrees).
Definition azimuth.hpp:316
std::vector< AzimuthCrossingEvent > azimuth_crossings(const Star &s, const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree bearing, const SearchOptions &opts={})
Find epochs when a star crosses a given azimuth bearing.
Definition azimuth.hpp:283
std::vector< Period< TT, MJD > > in_azimuth_range(const Star &s, const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree min_bearing, qtty::Degree max_bearing, const SearchOptions &opts={})
Find periods when a star's azimuth is within [min, max] (degrees).
Definition azimuth.hpp:299
qtty::Degree azimuth_at(const Star &s, const Geodetic &obs, const Time< TT, MJD > &mjd)
Compute a star's azimuth (degrees, N-clockwise) at a given Time<TT, MJD> instant.
Definition azimuth.hpp:272
std::vector< Period< TT, MJD > > in_azimuth_range(const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree min_bearing, qtty::Degree max_bearing, const SearchOptions &opts={})
Find periods when the Sun's azimuth is within [min_bearing, max_bearing].
Definition azimuth.hpp:151
std::vector< Period< TT, MJD > > outside_azimuth_range(const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree min_bearing, qtty::Degree max_bearing, const SearchOptions &opts={})
Find periods when the Sun's azimuth is outside [min_bearing, max_bearing].
Definition azimuth.hpp:167
std::vector< AzimuthCrossingEvent > azimuth_crossings(const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree bearing, const SearchOptions &opts={})
Find epochs when the Sun crosses a given bearing.
Definition azimuth.hpp:119
qtty::Degree azimuth_at(const Geodetic &obs, const Time< TT, MJD > &mjd)
Compute the Sun's azimuth (degrees, N-clockwise) at a given Time<TT, MJD> instant.
Definition azimuth.hpp:108
std::vector< AzimuthExtremum > azimuth_extrema(const Geodetic &obs, const Period< TT, MJD > &window, const SearchOptions &opts={})
Find azimuth extrema (northernmost / southernmost) for the Sun.
Definition azimuth.hpp:135
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
AzimuthExtremumKind
Distinguishes azimuth extrema: northernmost or southernmost bearing.
Definition azimuth.hpp:38
@ Max
Northernmost (or easternmost) direction reached by the body.
@ Min
Southernmost (or westernmost) direction reached by the body.
An azimuth bearing-crossing event.
Definition azimuth.hpp:46
Time< TT, MJD > time
Epoch of the crossing (Time<TT, MJD>).
Definition azimuth.hpp:47
static AzimuthCrossingEvent from_c(const siderust_azimuth_crossing_event_t &c)
Definition azimuth.hpp:50
CrossingDirection direction
Whether the azimuth is increasing or decreasing.
Definition azimuth.hpp:48
An azimuth extremum event.
Definition azimuth.hpp:58
AzimuthExtremumKind kind
Maximum or minimum.
Definition azimuth.hpp:61
Time< TT, MJD > time
Epoch of the extremum (Time<TT, MJD>).
Definition azimuth.hpp:59
static AzimuthExtremum from_c(const siderust_azimuth_extremum_t &c)
Definition azimuth.hpp:63
qtty::Degree azimuth
Azimuth at the extremum (degrees, N-clockwise).
Definition azimuth.hpp:60
Geodetic position (WGS84 ellipsoid).
Definition geodetic.hpp:29
siderust_geodetic_t to_c() const
Convert to C FFI struct.
Definition geodetic.hpp:44
Options for altitude search algorithms.
Definition altitude.hpp:58
A direction on the celestial sphere, compile-time tagged by frame.
Definition spherical.hpp:50
siderust_spherical_dir_t to_c() const
Public siderust time tags and typed time/period aliases.