...
This commit is contained in:
@@ -5,6 +5,15 @@
|
||||
|
||||
/* CELESTIAL COORDINATES TRANSFORMATION ENGINE IMPLEMENTATION BASED ON ERFA LIBRARY */
|
||||
|
||||
|
||||
// NOTE: according to definition of astronomical azimuth it is counted from the South through the West, but
|
||||
// in the ERFA the azimuth is counted from the North through the East!!!
|
||||
//
|
||||
// The implementation expects input azimuth as the "South"-defined one and transforms ERFA-outputs
|
||||
// to the "South"-defined one respectively
|
||||
|
||||
|
||||
|
||||
#include <erfa.h>
|
||||
#include <erfam.h>
|
||||
#include <mutex>
|
||||
@@ -115,7 +124,7 @@ inline std::error_code make_error_code(MccCCTE_ERFAErrorCode ec)
|
||||
|
||||
|
||||
|
||||
class MccCCTE_ERFA
|
||||
class MccCCTE_ERFA : public mcc_CCTE_interface_t<std::error_code>
|
||||
{
|
||||
static constexpr double PI_2 = std::numbers::pi / 2.0;
|
||||
|
||||
@@ -173,6 +182,12 @@ public:
|
||||
|
||||
virtual ~MccCCTE_ERFA() = default;
|
||||
|
||||
|
||||
std::string_view name() const
|
||||
{
|
||||
return "ERFA-CCTE-ENGINE";
|
||||
}
|
||||
|
||||
// engine state related methods
|
||||
|
||||
void setState(engine_state_t state)
|
||||
@@ -248,7 +263,7 @@ public:
|
||||
|
||||
error_t timepointToJulday(mcc_time_point_c auto tp, mcc_julday_c auto* julday)
|
||||
{
|
||||
auto ret = MccCCTE_ERFAErrorCode::ERROR_OK;
|
||||
error_t ret = MccCCTE_ERFAErrorCode::ERROR_OK;
|
||||
|
||||
if (julday == nullptr) {
|
||||
return ret;
|
||||
@@ -259,7 +274,7 @@ public:
|
||||
|
||||
double mjd0;
|
||||
|
||||
int err = eraCal2jd(ymd.year(), (unsigned)ymd.month(), (unsigned)ymd.day(), &mjd0, &julday->mjd);
|
||||
int err = eraCal2jd((int)ymd.year(), (unsigned)ymd.month(), (unsigned)ymd.day(), &mjd0, &julday->mjd);
|
||||
|
||||
if (err != 0) {
|
||||
ret = err == -1 ? MccCCTE_ERFAErrorCode::ERROR_julday_INVALID_YEAR
|
||||
@@ -277,7 +292,7 @@ public:
|
||||
|
||||
error_t timepointToAppSideral(mcc_time_point_c auto tp, mcc_angle_c auto* st, bool islocal = false)
|
||||
{
|
||||
auto ret = MccCCTE_ERFAErrorCode::ERROR_OK;
|
||||
error_t ret = MccCCTE_ERFAErrorCode::ERROR_OK;
|
||||
|
||||
if (st == nullptr) {
|
||||
return ret;
|
||||
@@ -401,8 +416,9 @@ public:
|
||||
|
||||
// from apparent to apparent
|
||||
if (from_pt.time_point != to_pt->time_point) { // first, convert 'from' coordinates to ICRS
|
||||
MccCelestialPoint pt{.time_point = to_pt->time_point,
|
||||
.pair_kind = MccCoordPairKind::COORDS_KIND_RADEC_ICRS};
|
||||
MccCelestialPoint pt{.pair_kind = MccCoordPairKind::COORDS_KIND_RADEC_ICRS};
|
||||
pt.time_point = to_pt->time_point;
|
||||
|
||||
ret = obs2icrs(from_pt, &pt);
|
||||
|
||||
if (!ret) { // from ICRS to required
|
||||
@@ -428,13 +444,12 @@ public:
|
||||
}
|
||||
|
||||
if (to_pt->pair_kind == MccCoordPairKind::COORDS_KIND_AZZD) {
|
||||
eraHd2ae(ha, from_pt.Y, _currentState.lat, &az, &alt);
|
||||
to_pt->X = az;
|
||||
to_pt->Y = PI_2 - alt;
|
||||
from_pt.X = ha;
|
||||
hadec2azalt(from_pt, to_pt);
|
||||
to_pt->Y = PI_2 - to_pt->Y;
|
||||
} else if (to_pt->pair_kind == MccCoordPairKind::COORDS_KIND_AZALT) {
|
||||
eraHd2ae(ha, from_pt.Y, _currentState.lat, &az, &alt);
|
||||
to_pt->X = az;
|
||||
to_pt->Y = alt;
|
||||
from_pt.X = ha;
|
||||
hadec2azalt(from_pt, to_pt);
|
||||
} else if (to_pt->pair_kind == MccCoordPairKind::COORDS_KIND_HADEC_APP) {
|
||||
to_pt->X = ha;
|
||||
to_pt->Y = from_pt.Y;
|
||||
@@ -443,13 +458,10 @@ public:
|
||||
}
|
||||
} else if (from_pt.pair_kind == MccCoordPairKind::COORDS_KIND_HADEC_APP) {
|
||||
if (to_pt->pair_kind == MccCoordPairKind::COORDS_KIND_AZZD) {
|
||||
eraHd2ae(ha, from_pt.Y, _currentState.lat, &az, &alt);
|
||||
to_pt->X = az;
|
||||
to_pt->Y = PI_2 - alt;
|
||||
hadec2azalt(from_pt, to_pt);
|
||||
to_pt->Y = PI_2 - to_pt->Y;
|
||||
} else if (to_pt->pair_kind == MccCoordPairKind::COORDS_KIND_AZALT) {
|
||||
eraHd2ae(ha, from_pt.Y, _currentState.lat, &az, &alt);
|
||||
to_pt->X = az;
|
||||
to_pt->Y = alt;
|
||||
hadec2azalt(from_pt, to_pt);
|
||||
} else if (to_pt->pair_kind == MccCoordPairKind::COORDS_KIND_RADEC_APP) {
|
||||
lst_eo();
|
||||
if (!ret) {
|
||||
@@ -469,18 +481,15 @@ public:
|
||||
ret = transformCoordinates(std::move(from_pt), to_pt);
|
||||
} else if (from_pt.pair_kind == MccCoordPairKind::COORDS_KIND_AZALT) {
|
||||
if (to_pt->pair_kind == MccCoordPairKind::COORDS_KIND_HADEC_APP) {
|
||||
eraAe2hd(from_pt.X, from_pt.Y, _currentState.lat, &ha, &dec);
|
||||
to_pt->X = ha;
|
||||
to_pt->Y = dec;
|
||||
azalt2hadec(from_pt, to_pt);
|
||||
} else if (to_pt->pair_kind == MccCoordPairKind::COORDS_KIND_AZZD) {
|
||||
to_pt->X = from_pt.X;
|
||||
to_pt->Y = PI_2 - from_pt.Y;
|
||||
} else if (to_pt->pair_kind == MccCoordPairKind::COORDS_KIND_RADEC_APP) {
|
||||
eraAe2hd(from_pt.X, from_pt.Y, _currentState.lat, &ha, &dec);
|
||||
azalt2hadec(from_pt, to_pt);
|
||||
lst_eo();
|
||||
if (!ret) {
|
||||
to_pt->X = lst - ha + eo;
|
||||
to_pt->Y = dec;
|
||||
to_pt->X = lst - to_pt->X + eo;
|
||||
}
|
||||
} else {
|
||||
ret = MccCCTE_ERFAErrorCode::ERROR_UNSUPPORTED_COORD_PAIR;
|
||||
@@ -711,18 +720,22 @@ protected:
|
||||
ret = MccCCTE_ERFAErrorCode::ERROR_UNACCEPTABLE_DATE;
|
||||
}
|
||||
|
||||
result->AZ = az;
|
||||
|
||||
// NOTE: according to definition of astronomical azimuth it is counted from the South through the West, but
|
||||
// in the ERFA the azimuth is counted from the North through the East!!!
|
||||
//
|
||||
result->AZ = MccAngle(az + std::numbers::pi).normalize<MccAngle::NORM_KIND_0_360>();
|
||||
result->ZD = zd;
|
||||
result->HA = ha;
|
||||
result->RA_APP = ra;
|
||||
result->DEC_APP = dec;
|
||||
result->ALT = std::numbers::pi / 2.0 - zd;
|
||||
result->ALT = MccCCTE_ERFA::PI_2 - zd;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
error_t obs2icrs(mcc_celestial_point_c auto const& from_pt, mcc_celestial_point_c auto* to_pt)
|
||||
error_t obs2icrs(mcc_celestial_point_c auto from_pt, mcc_celestial_point_c auto* to_pt)
|
||||
{
|
||||
if (to_pt == nullptr) {
|
||||
return MccCCTE_ERFAErrorCode::ERROR_OK;
|
||||
@@ -756,10 +769,18 @@ protected:
|
||||
std::string type;
|
||||
switch (from_pt.pair_kind) {
|
||||
case mcc::MccCoordPairKind::COORDS_KIND_AZZD:
|
||||
// NOTE: according to definition of astronomical azimuth it is counted from the South through the West,
|
||||
// but in the ERFA the azimuth is counted from the North through the East!!!
|
||||
//
|
||||
from_pt.X += std::numbers::pi;
|
||||
type = "A";
|
||||
break;
|
||||
case mcc::MccCoordPairKind::COORDS_KIND_AZALT:
|
||||
from_pt.Y = std::numbers::pi / 2.0 - from_pt.Y; // altitude to zenithal distance
|
||||
// NOTE: according to definition of astronomical azimuth it is counted from the South through the West,
|
||||
// but in the ERFA the azimuth is counted from the North through the East!!!
|
||||
//
|
||||
from_pt.X += std::numbers::pi;
|
||||
from_pt.Y = MccCCTE_ERFA::PI_2 - from_pt.Y; // altitude to zenithal distance
|
||||
type = "A";
|
||||
break;
|
||||
case mcc::MccCoordPairKind::COORDS_KIND_HADEC_APP:
|
||||
@@ -778,10 +799,41 @@ protected:
|
||||
&to_pt->X, &to_pt->Y);
|
||||
|
||||
if (err == 1) {
|
||||
return MccCCTE_ERFAErrorCode::ERROR_DUBIOUS_YEAR;
|
||||
ret = MccCCTE_ERFAErrorCode::ERROR_DUBIOUS_YEAR;
|
||||
} else if (err == -1) {
|
||||
return MccCCTE_ERFAErrorCode::ERROR_UNACCEPTABLE_DATE;
|
||||
ret = MccCCTE_ERFAErrorCode::ERROR_UNACCEPTABLE_DATE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void azalt2hadec(mcc_celestial_point_c auto const& from_pt, mcc_celestial_point_c auto* to_pt)
|
||||
{
|
||||
double ha, dec;
|
||||
|
||||
// NOTE: according to definition of astronomical azimuth it is counted from the South through the West, but
|
||||
// in the ERFA the azimuth is counted from the North through the East!!!
|
||||
//
|
||||
eraAe2hd(from_pt.X + std::numbers::pi, from_pt.Y, _currentState.lat, &ha, &dec);
|
||||
|
||||
to_pt->X = ha;
|
||||
to_pt->Y = dec;
|
||||
}
|
||||
|
||||
|
||||
void hadec2azalt(mcc_celestial_point_c auto const& from_pt, mcc_celestial_point_c auto* to_pt)
|
||||
{
|
||||
double az, alt;
|
||||
|
||||
eraHd2ae(from_pt.X, from_pt.Y, _currentState.lat, &az, &alt);
|
||||
|
||||
// NOTE: according to definition of astronomical azimuth it is counted from the South through the West, but
|
||||
// in the ERFA the azimuth is counted from the North through the East!!!
|
||||
//
|
||||
// convert it to "from the South through the West"
|
||||
to_pt->X = MccAngle(az - std::numbers::pi).normalize<MccAngle::NORM_KIND_0_360>();
|
||||
to_pt->Y = alt;
|
||||
}
|
||||
|
||||
error_t eqOrigins(mcc_time_point_c auto const& tp, double* eo)
|
||||
@@ -816,4 +868,6 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(mcc_ccte_c<MccCCTE_ERFA>, "");
|
||||
|
||||
} // namespace mcc::ccte::erfa
|
||||
|
||||
Reference in New Issue
Block a user