This commit is contained in:
Timur A. Fatkhullin 2025-04-22 18:43:32 +03:00
parent f8aaccb06d
commit f0378a063f

View File

@ -103,23 +103,37 @@ private:
enum class MccAltLimitKind { MIN_ALT_LIMIT, MAX_ALT_LIMIT };
template <MccAltLimitKind LIMIT = MccAltLimitKind::MIN_ALT_LIMIT>
template <MccAltLimitKind KIND = MccAltLimitKind::MIN_ALT_LIMIT>
class MccAltLimitPZ
{
public:
static constexpr MccAltLimitKind altLimitType = LIMIT;
static constexpr MccAltLimitKind altLimitKind = KIND;
MccAltLimitPZ(const MccAngle& alt_limit) : _altLimit(alt_limit)
{
_altLimit.normalize<MccAngle::NORM_KIND_90_90>();
}
std::string_view name() const
{
return KIND == MccAltLimitKind::MIN_ALT_LIMIT ? "MINALT-ZONE"
: KIND == MccAltLimitKind::MAX_ALT_LIMIT ? "MAXALT-ZONE"
: "ALTLIMIT-UNKNOWN";
}
std::string_view desc() const
{
return KIND == MccAltLimitKind::MIN_ALT_LIMIT ? "Minimal altitude prohibited zone"
: KIND == MccAltLimitKind::MAX_ALT_LIMIT ? "Maximal altitude prohibited zone"
: "Unknown altitude prohibited zone";
}
bool inZone(const MccAngle& x, const MccAngle& y, const MccProhibitedZone::pzcontext_t& context)
{
if (context.coords_kind == MccProhibitedZone::COORDS_KIND_AZALT) { // trivial case
if constexpr (LIMIT == MccAltLimitKind::MIN_ALT_LIMIT) {
if constexpr (KIND == MccAltLimitKind::MIN_ALT_LIMIT) {
return y <= _altLimit;
} else if constexpr (LIMIT == MccAltLimitKind::MAX_ALT_LIMIT) {
} else if constexpr (KIND == MccAltLimitKind::MAX_ALT_LIMIT) {
return y >= _altLimit;
}
} else if (context.coords_kind == MccProhibitedZone::COORDS_KIND_RADEC_APP) {
@ -135,6 +149,64 @@ public:
const MccProhibitedZone::pzcontext_t& context,
traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
{
if (context.coords_kind == MccProhibitedZone::COORDS_KIND_RADEC_APP) {
auto dd = astrom::mcc_time_to_alt(_altLimit, x, y, context.lat, context.lon, utc, context.dut1,
context.tt_tai, context.tai_utc);
if (std::isnan(dd.first)) { // error!
throw std::system_error(std::make_error_code(std::errc::invalid_argument));
}
if (std::isinf(dd.first)) { // never reach zone
return dd.first;
}
if constexpr (KIND == MccAltLimitKind::MIN_ALT_LIMIT) {
if (dd.first <= dd.second) { // in zone
return decltype(dd.first)(0.0);
}
} else if constexpr (KIND == MccAltLimitKind::MAX_ALT_LIMIT) {
if (dd.first >= dd.second) { // in zone
return decltype(dd.first)(0.0);
}
}
return dd.second;
} else {
throw std::system_error(std::make_error_code(std::errc::operation_not_supported));
}
}
auto timeFrom(const MccAngle& x,
const MccAngle& y,
const MccProhibitedZone::pzcontext_t& context,
traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
{
if (context.coords_kind == MccProhibitedZone::COORDS_KIND_RADEC_APP) {
auto dd = astrom::mcc_time_to_alt(_altLimit, x, y, context.lat, context.lon, utc, context.dut1,
context.tt_tai, context.tai_utc);
if (std::isnan(dd.first)) { // error!
throw std::system_error(std::make_error_code(std::errc::invalid_argument));
}
if (std::isinf(dd.first)) { // never reach zone
return dd.first;
}
if constexpr (KIND == MccAltLimitKind::MIN_ALT_LIMIT) {
if (dd.first > dd.second) { // not in zone
return decltype(dd.first)(0.0);
}
} else if constexpr (KIND == MccAltLimitKind::MAX_ALT_LIMIT) {
if (dd.first < dd.second) { // not in zone
return decltype(dd.first)(0.0);
}
}
return dd.first;
} else {
throw std::system_error(std::make_error_code(std::errc::operation_not_supported));
}
}
private: