siderust-cpp
Header-only C++ wrapper for siderust
Loading...
Searching...
No Matches
spherical.hpp
Go to the documentation of this file.
1#pragma once
2
9#include "../centers.hpp"
10#include "../frames.hpp"
11#include "../time.hpp"
12#include "geodetic.hpp"
13
14#include <qtty/qtty.hpp>
15
16#include <type_traits>
17
18namespace siderust {
19namespace spherical {
20
35template <typename F>
36struct Direction {
37 static_assert(frames::is_frame_v<F>, "F must be a valid frame tag");
38
39 private:
40 qtty::Degree azimuth_;
41 qtty::Degree polar_;
42
43 public:
44 Direction() : azimuth_(qtty::Degree(0)), polar_(qtty::Degree(0)) {}
45
46 Direction(qtty::Degree azimuth, qtty::Degree polar)
47 : azimuth_(azimuth), polar_(polar) {}
48
50 Direction(double azimuth_deg, double polar_deg)
51 : azimuth_(qtty::Degree(azimuth_deg)), polar_(qtty::Degree(polar_deg)) {}
52
55 static constexpr siderust_frame_t frame_id() {
57 }
58 static constexpr const char* frame_name() {
60 }
62
65 template <typename F_ = F, std::enable_if_t<frames::has_ra_dec_v<F_>, int> = 0>
66 qtty::Degree ra() const { return azimuth_; }
67
68 template <typename F_ = F, std::enable_if_t<frames::has_ra_dec_v<F_>, int> = 0>
69 qtty::Degree dec() const { return polar_; }
71
74 template <typename F_ = F, std::enable_if_t<frames::has_az_alt_v<F_>, int> = 0>
75 qtty::Degree az() const { return azimuth_; }
76
77 template <typename F_ = F, std::enable_if_t<frames::has_az_alt_v<F_>, int> = 0>
78 qtty::Degree al() const { return polar_; }
79
80 template <typename F_ = F, std::enable_if_t<frames::has_az_alt_v<F_>, int> = 0>
81 qtty::Degree alt() const { return polar_; }
82
83 template <typename F_ = F, std::enable_if_t<frames::has_az_alt_v<F_>, int> = 0>
84 qtty::Degree altitude() const { return polar_; }
86
89 template <typename F_ = F, std::enable_if_t<frames::has_lon_lat_v<F_>, int> = 0>
90 qtty::Degree lon() const { return azimuth_; }
91
92 template <typename F_ = F, std::enable_if_t<frames::has_lon_lat_v<F_>, int> = 0>
93 qtty::Degree lat() const { return polar_; }
94
95 template <typename F_ = F, std::enable_if_t<frames::has_lon_lat_v<F_>, int> = 0>
96 qtty::Degree longitude() const { return azimuth_; }
97
98 template <typename F_ = F, std::enable_if_t<frames::has_lon_lat_v<F_>, int> = 0>
99 qtty::Degree latitude() const { return polar_; }
101
104 siderust_spherical_dir_t to_c() const {
105 return {azimuth_.value(), polar_.value(), frame_id()};
106 }
107
108 static Direction from_c(const siderust_spherical_dir_t& c) {
109 return Direction(c.lon_deg, c.lat_deg);
110 }
112
121 template <typename Target>
122 std::enable_if_t<
123 frames::has_frame_transform_v<F, Target>,
125 to_frame(const JulianDate& jd) const {
126 if constexpr (std::is_same_v<F, Target>) {
127 return Direction<Target>(azimuth_.value(), polar_.value());
128 } else {
129 siderust_spherical_dir_t out;
131 siderust_spherical_dir_transform_frame(
132 azimuth_.value(), polar_.value(),
135 jd.value(), &out),
136 "Direction::to_frame");
137 return Direction<Target>::from_c(out);
138 }
139 }
140
144 template <typename Target>
145 auto to(const JulianDate& jd) const
146 -> decltype(this->template to_frame<Target>(jd)) {
147 return to_frame<Target>(jd);
148 }
149
153 template <typename F_ = F>
154 std::enable_if_t<
155 frames::has_horizontal_transform_v<F_>,
157 to_horizontal(const JulianDate& jd, const Geodetic& observer) const {
158 siderust_spherical_dir_t out;
160 siderust_spherical_dir_to_horizontal(
161 azimuth_.value(), polar_.value(),
163 jd.value(), observer.to_c(), &out),
164 "Direction::to_horizontal");
166 }
167};
168
179template <typename C, typename F, typename U = qtty::Meter>
180struct Position {
181 static_assert(frames::is_frame_v<F>, "F must be a valid frame tag");
182 static_assert(centers::is_center_v<C>, "C must be a valid center tag");
183
184 private:
185 qtty::Degree azimuth_;
186 qtty::Degree polar_;
187 U dist_;
188
189 public:
191 : azimuth_(qtty::Degree(0)), polar_(qtty::Degree(0)), dist_(U(0)) {}
192
193 Position(qtty::Degree azimuth, qtty::Degree polar, U dist)
194 : azimuth_(azimuth), polar_(polar), dist_(dist) {}
195
196 Position(double azimuth_deg, double polar_deg, double dist_val)
197 : azimuth_(qtty::Degree(azimuth_deg)),
198 polar_(qtty::Degree(polar_deg)),
199 dist_(U(dist_val)) {}
200
203 return Direction<F>(azimuth_, polar_);
204 }
205
208 template <typename F_ = F, std::enable_if_t<frames::has_ra_dec_v<F_>, int> = 0>
209 qtty::Degree ra() const { return azimuth_; }
210
211 template <typename F_ = F, std::enable_if_t<frames::has_ra_dec_v<F_>, int> = 0>
212 qtty::Degree dec() const { return polar_; }
213
214 template <typename F_ = F, std::enable_if_t<frames::has_az_alt_v<F_>, int> = 0>
215 qtty::Degree az() const { return azimuth_; }
216
217 template <typename F_ = F, std::enable_if_t<frames::has_az_alt_v<F_>, int> = 0>
218 qtty::Degree al() const { return polar_; }
219
220 template <typename F_ = F, std::enable_if_t<frames::has_az_alt_v<F_>, int> = 0>
221 qtty::Degree alt() const { return polar_; }
222
223 template <typename F_ = F, std::enable_if_t<frames::has_lon_lat_v<F_>, int> = 0>
224 qtty::Degree lon() const { return azimuth_; }
225
226 template <typename F_ = F, std::enable_if_t<frames::has_lon_lat_v<F_>, int> = 0>
227 qtty::Degree lat() const { return polar_; }
229
230 static constexpr siderust_frame_t frame_id() { return frames::FrameTraits<F>::ffi_id; }
231 static constexpr siderust_center_t center_id() { return centers::CenterTraits<C>::ffi_id; }
232
233 U distance() const { return dist_; }
234};
235
236} // namespace spherical
237} // namespace siderust
void check_status(siderust_status_t status, const char *operation)
Definition ffi_core.hpp:81
tempoch::JulianDate JulianDate
Definition time.hpp:17
Geodetic position (WGS84 ellipsoid).
Definition geodetic.hpp:28
siderust_geodetic_t to_c() const
Convert to C FFI struct.
Definition geodetic.hpp:45
SFINAE helper: every frame tag must provide these static members.
Definition frames.hpp:28
A direction on the celestial sphere, compile-time tagged by frame.
Definition spherical.hpp:36
qtty::Degree lon() const
Definition spherical.hpp:90
qtty::Degree al() const
Definition spherical.hpp:78
qtty::Degree lat() const
Definition spherical.hpp:93
static constexpr siderust_frame_t frame_id()
Definition spherical.hpp:55
std::enable_if_t< frames::has_frame_transform_v< F, Target >, Direction< Target > > to_frame(const JulianDate &jd) const
Transform to a different reference frame.
qtty::Degree alt() const
Definition spherical.hpp:81
Direction(qtty::Degree azimuth, qtty::Degree polar)
Definition spherical.hpp:46
qtty::Degree az() const
Definition spherical.hpp:75
std::enable_if_t< frames::has_horizontal_transform_v< F_ >, Direction< frames::Horizontal > > to_horizontal(const JulianDate &jd, const Geodetic &observer) const
Transform to the horizontal (alt-az) frame.
qtty::Degree latitude() const
Definition spherical.hpp:99
static constexpr const char * frame_name()
Definition spherical.hpp:58
qtty::Degree altitude() const
Definition spherical.hpp:84
siderust_spherical_dir_t to_c() const
auto to(const JulianDate &jd) const -> decltype(this->template to_frame< Target >(jd))
Shorthand: .to<Target>(jd) (calls to_frame).
qtty::Degree dec() const
Definition spherical.hpp:69
qtty::Degree ra() const
Definition spherical.hpp:66
Direction(double azimuth_deg, double polar_deg)
Raw-double convenience (degrees).
Definition spherical.hpp:50
qtty::Degree longitude() const
Definition spherical.hpp:96
static Direction from_c(const siderust_spherical_dir_t &c)
A spherical position (direction + distance), compile-time tagged.
Position(qtty::Degree azimuth, qtty::Degree polar, U dist)
static constexpr siderust_center_t center_id()
Direction< F > direction() const
Extract the direction component.
static constexpr siderust_frame_t frame_id()
qtty::Degree ra() const
qtty::Degree alt() const
qtty::Degree az() const
qtty::Degree dec() const
qtty::Degree lon() const
Position(double azimuth_deg, double polar_deg, double dist_val)
qtty::Degree al() const
qtty::Degree lat() const