siderust-cpp 0.8.0
Header-only C++ wrapper for siderust
Loading...
Searching...
No Matches
body_target.hpp
Go to the documentation of this file.
1#pragma once
2
30#include "altitude.hpp"
31#include "azimuth.hpp"
32#include "ffi_core.hpp"
33#include "trackable.hpp"
34#include <string>
35
36namespace siderust {
37
38// ============================================================================
39// Body enum
40// ============================================================================
41
47enum class Body : int32_t {
48 Sun = SIDERUST_BODY_SUN,
49 Moon = SIDERUST_BODY_MOON,
50 Mercury = SIDERUST_BODY_MERCURY,
51 Venus = SIDERUST_BODY_VENUS,
52 Mars = SIDERUST_BODY_MARS,
53 Jupiter = SIDERUST_BODY_JUPITER,
54 Saturn = SIDERUST_BODY_SATURN,
55 Uranus = SIDERUST_BODY_URANUS,
56 Neptune = SIDERUST_BODY_NEPTUNE,
57};
58
59// ============================================================================
60// Free functions in body:: namespace
61// ============================================================================
62
63namespace body {
64
68inline qtty::Radian altitude_at(Body b, const Geodetic &obs, const Time<TT, MJD> &mjd) {
69 double out;
70 check_status(siderust_altitude_at(detail::make_body_subject(static_cast<SiderustBody>(b)),
71 obs.to_c(), mjd.value(), &out),
72 "body::altitude_at");
73 return qtty::Radian(out);
74}
75
79inline std::vector<Period<TT, MJD>> above_threshold(Body b, const Geodetic &obs,
80 const Period<TT, MJD> &window,
81 qtty::Degree threshold,
82 const SearchOptions &opts = {}) {
83 tempoch_period_mjd_t *ptr = nullptr;
84 uintptr_t count = 0;
85 check_status(siderust_above_threshold(detail::make_body_subject(static_cast<SiderustBody>(b)),
86 obs.to_c(), window.c_inner(), threshold.value(),
87 opts.to_c(), &ptr, &count),
88 "body::above_threshold");
89 return detail::periods_from_c(ptr, count);
90}
91
95inline std::vector<Period<TT, MJD>> below_threshold(Body b, const Geodetic &obs,
96 const Period<TT, MJD> &window,
97 qtty::Degree threshold,
98 const SearchOptions &opts = {}) {
99 tempoch_period_mjd_t *ptr = nullptr;
100 uintptr_t count = 0;
101 check_status(siderust_below_threshold(detail::make_body_subject(static_cast<SiderustBody>(b)),
102 obs.to_c(), window.c_inner(), threshold.value(),
103 opts.to_c(), &ptr, &count),
104 "body::below_threshold");
105 return detail::periods_from_c(ptr, count);
106}
107
111inline std::vector<CrossingEvent> crossings(Body b, const Geodetic &obs,
112 const Period<TT, MJD> &window, qtty::Degree threshold,
113 const SearchOptions &opts = {}) {
114 siderust_crossing_event_t *ptr = nullptr;
115 uintptr_t count = 0;
116 check_status(siderust_crossings(detail::make_body_subject(static_cast<SiderustBody>(b)),
117 obs.to_c(), window.c_inner(), threshold.value(), opts.to_c(),
118 &ptr, &count),
119 "body::crossings");
120 return detail::crossings_from_c(ptr, count);
121}
122
126inline std::vector<CulminationEvent> culminations(Body b, const Geodetic &obs,
127 const Period<TT, MJD> &window,
128 const SearchOptions &opts = {}) {
129 siderust_culmination_event_t *ptr = nullptr;
130 uintptr_t count = 0;
131 check_status(siderust_culminations(detail::make_body_subject(static_cast<SiderustBody>(b)),
132 obs.to_c(), window.c_inner(), opts.to_c(), &ptr, &count),
133 "body::culminations");
134 return detail::culminations_from_c(ptr, count);
135}
136
140inline std::vector<Period<TT, MJD>> altitude_ranges(Body b, const Geodetic &obs,
141 const Period<TT, MJD> &window,
142 qtty::Degree min_alt, qtty::Degree max_alt,
143 const SearchOptions &opts = {}) {
144 tempoch_period_mjd_t *ptr = nullptr;
145 uintptr_t count = 0;
146 check_status(siderust_altitude_ranges(detail::make_body_subject(static_cast<SiderustBody>(b)),
147 obs.to_c(), window.c_inner(), min_alt.value(),
148 max_alt.value(), opts.to_c(), &ptr, &count),
149 "body::altitude_ranges");
150 return detail::periods_from_c(ptr, count);
151}
152
153} // namespace body
154
155namespace body {
156
157// ── Azimuth free functions ──────────────────────────────────────────────
158
162inline qtty::Radian azimuth_at(Body b, const Geodetic &obs, const Time<TT, MJD> &mjd) {
163 double out;
164 check_status(siderust_azimuth_at(detail::make_body_subject(static_cast<SiderustBody>(b)),
165 obs.to_c(), mjd.value(), &out),
166 "body::azimuth_at");
167 return qtty::Radian(out);
168}
169
173inline std::vector<AzimuthCrossingEvent> azimuth_crossings(Body b, const Geodetic &obs,
174 const Period<TT, MJD> &window,
175 qtty::Degree bearing,
176 const SearchOptions &opts = {}) {
177 siderust_azimuth_crossing_event_t *ptr = nullptr;
178 uintptr_t count = 0;
179 check_status(siderust_azimuth_crossings(detail::make_body_subject(static_cast<SiderustBody>(b)),
180 obs.to_c(), window.c_inner(), bearing.value(),
181 opts.to_c(), &ptr, &count),
182 "body::azimuth_crossings");
183 return detail::az_crossings_from_c(ptr, count);
184}
185
189inline std::vector<AzimuthExtremum> azimuth_extrema(Body b, const Geodetic &obs,
190 const Period<TT, MJD> &window,
191 const SearchOptions &opts = {}) {
192 siderust_azimuth_extremum_t *ptr = nullptr;
193 uintptr_t count = 0;
194 check_status(siderust_azimuth_extrema(detail::make_body_subject(static_cast<SiderustBody>(b)),
195 obs.to_c(), window.c_inner(), opts.to_c(), &ptr, &count),
196 "body::azimuth_extrema");
197 return detail::az_extrema_from_c(ptr, count);
198}
199
203inline std::vector<Period<TT, MJD>> in_azimuth_range(Body b, const Geodetic &obs,
204 const Period<TT, MJD> &window,
205 qtty::Degree min, qtty::Degree max,
206 const SearchOptions &opts = {}) {
207 tempoch_period_mjd_t *ptr = nullptr;
208 uintptr_t count = 0;
209 check_status(siderust_in_azimuth_range(detail::make_body_subject(static_cast<SiderustBody>(b)),
210 obs.to_c(), window.c_inner(), min.value(), max.value(),
211 opts.to_c(), &ptr, &count),
212 "body::in_azimuth_range");
213 return detail::periods_from_c(ptr, count);
214}
215
216} // namespace body
217
218// ============================================================================
219// BodyTarget — Target implementation for solar-system bodies
220// ============================================================================
221
232class BodyTarget : public Target {
233public:
238 explicit BodyTarget(Body body) : body_(body) {}
239
240 // ------------------------------------------------------------------
241 // Identity (implements Target)
242 // ------------------------------------------------------------------
243
247 std::string name() const override {
248 switch (body_) {
249 case Body::Sun:
250 return "Sun";
251 case Body::Moon:
252 return "Moon";
253 case Body::Mercury:
254 return "Mercury";
255 case Body::Venus:
256 return "Venus";
257 case Body::Mars:
258 return "Mars";
259 case Body::Jupiter:
260 return "Jupiter";
261 case Body::Saturn:
262 return "Saturn";
263 case Body::Uranus:
264 return "Uranus";
265 case Body::Neptune:
266 return "Neptune";
267 default:
268 return "Unknown Body";
269 }
270 }
271
272 // ------------------------------------------------------------------
273 // Altitude queries
274 // ------------------------------------------------------------------
275
276 qtty::Degree altitude_at(const Geodetic &obs, const Time<TT, MJD> &mjd) const override {
277 auto rad = body::altitude_at(body_, obs, mjd);
278 return qtty::Degree(rad.value() * 180.0 / 3.14159265358979323846);
279 }
280
281 std::vector<Period<TT, MJD>> above_threshold(const Geodetic &obs, const Period<TT, MJD> &window,
282 qtty::Degree threshold,
283 const SearchOptions &opts = {}) const override {
284 return body::above_threshold(body_, obs, window, threshold, opts);
285 }
286
287 std::vector<Period<TT, MJD>> below_threshold(const Geodetic &obs, const Period<TT, MJD> &window,
288 qtty::Degree threshold,
289 const SearchOptions &opts = {}) const override {
290 return body::below_threshold(body_, obs, window, threshold, opts);
291 }
292
293 std::vector<CrossingEvent> crossings(const Geodetic &obs, const Period<TT, MJD> &window,
294 qtty::Degree threshold,
295 const SearchOptions &opts = {}) const override {
296 return body::crossings(body_, obs, window, threshold, opts);
297 }
298
299 std::vector<CulminationEvent> culminations(const Geodetic &obs, const Period<TT, MJD> &window,
300 const SearchOptions &opts = {}) const override {
301 return body::culminations(body_, obs, window, opts);
302 }
303
304 // ------------------------------------------------------------------
305 // Azimuth queries
306 // ------------------------------------------------------------------
307
308 qtty::Degree azimuth_at(const Geodetic &obs, const Time<TT, MJD> &mjd) const override {
309 auto rad = body::azimuth_at(body_, obs, mjd);
310 return qtty::Degree(rad.value() * 180.0 / 3.14159265358979323846);
311 }
312
313 std::vector<AzimuthCrossingEvent>
314 azimuth_crossings(const Geodetic &obs, const Period<TT, MJD> &window, qtty::Degree bearing,
315 const SearchOptions &opts = {}) const override {
316 return body::azimuth_crossings(body_, obs, window, bearing, opts);
317 }
318
320 Body body() const { return body_; }
321
322private:
323 Body body_;
324};
325
326} // namespace siderust
Altitude computations for Sun, Moon, stars, and arbitrary ICRS directions.
Azimuth computations for Sun, Moon, stars, and arbitrary ICRS directions.
Target implementation for solar-system bodies.
std::vector< Period< TT, MJD > > below_threshold(const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree threshold, const SearchOptions &opts={}) const override
Find periods when the object is below a threshold altitude.
qtty::Degree altitude_at(const Geodetic &obs, const Time< TT, MJD > &mjd) const override
Compute altitude (degrees) at a given Time<TT, MJD> instant.
std::vector< Period< TT, MJD > > above_threshold(const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree threshold, const SearchOptions &opts={}) const override
Find periods when the object is above a threshold altitude.
std::vector< CrossingEvent > crossings(const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree threshold, const SearchOptions &opts={}) const override
Find threshold-crossing events (rising / setting).
std::vector< AzimuthCrossingEvent > azimuth_crossings(const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree bearing, const SearchOptions &opts={}) const override
Find epochs when the object crosses a given azimuth bearing.
Body body() const
Access the underlying Body enum value.
std::vector< CulminationEvent > culminations(const Geodetic &obs, const Period< TT, MJD > &window, const SearchOptions &opts={}) const override
Find culmination (local altitude extremum) events.
BodyTarget(Body body)
Construct a BodyTarget for a given solar-system body.
qtty::Degree azimuth_at(const Geodetic &obs, const Time< TT, MJD > &mjd) const override
Compute azimuth (degrees, N-clockwise) at a given Time<TT, MJD> instant.
std::string name() const override
Returns the body's conventional name ("Sun", "Moon", "Mars", …).
Abstract base for any celestial object that can be tracked from an observer location.
Definition trackable.hpp:54
Error handling and utility base for the siderust C++ wrapper.
std::vector< Period< TT, MJD > > below_threshold(Body b, const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree threshold, const SearchOptions &opts={})
Find periods when a body is below a threshold altitude.
std::vector< Period< TT, MJD > > altitude_ranges(Body b, const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree min_alt, qtty::Degree max_alt, const SearchOptions &opts={})
Find periods when a body's altitude is within [min, max].
std::vector< Period< TT, MJD > > in_azimuth_range(Body b, const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree min, qtty::Degree max, const SearchOptions &opts={})
Find periods when a body's azimuth is within [min, max].
qtty::Radian altitude_at(Body b, const Geodetic &obs, const Time< TT, MJD > &mjd)
Compute a body's altitude (radians) at a given Time<TT, MJD> instant.
std::vector< Period< TT, MJD > > above_threshold(Body b, const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree threshold, const SearchOptions &opts={})
Find periods when a body is above a threshold altitude.
qtty::Radian azimuth_at(Body b, const Geodetic &obs, const Time< TT, MJD > &mjd)
Compute a body's azimuth (radians) at a given Time<TT, MJD> instant.
std::vector< CrossingEvent > crossings(Body b, const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree threshold, const SearchOptions &opts={})
Find threshold-crossing events for a body.
std::vector< AzimuthExtremum > azimuth_extrema(Body b, const Geodetic &obs, const Period< TT, MJD > &window, const SearchOptions &opts={})
Find azimuth extrema (northernmost/southernmost bearing) for a body.
std::vector< AzimuthCrossingEvent > azimuth_crossings(Body b, const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree bearing, const SearchOptions &opts={})
Find azimuth-bearing crossing events for a body.
std::vector< CulminationEvent > culminations(Body b, const Geodetic &obs, const Period< TT, MJD > &window, const SearchOptions &opts={})
Find culmination events for a body.
std::vector< AzimuthExtremum > az_extrema_from_c(siderust_azimuth_extremum_t *ptr, uintptr_t count)
Definition azimuth.hpp:85
std::vector< CrossingEvent > crossings_from_c(siderust_crossing_event_t *ptr, uintptr_t count)
Definition altitude.hpp:87
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< CulminationEvent > culminations_from_c(siderust_culmination_event_t *ptr, uintptr_t count)
Definition altitude.hpp:98
std::vector< AzimuthCrossingEvent > az_crossings_from_c(siderust_azimuth_crossing_event_t *ptr, uintptr_t count)
Definition azimuth.hpp:74
std::vector< Period< TT, MJD > > periods_from_c(tempoch_period_mjd_t *ptr, uintptr_t count)
Definition altitude.hpp:77
tempoch::EncodedTime< Scale, Format > Time
Definition time.hpp:36
void check_status(siderust_status_t status, const char *operation)
Definition ffi_core.hpp:111
tempoch::Period< Time< Scale, Format > > Period
Definition time.hpp:37
Body
Identifies a solar-system body for generic altitude/azimuth dispatch.
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
Abstract base class for all celestial targets.