From 78e1a7d71d64b433d2246be8b11f039f58c3d4e6 Mon Sep 17 00:00:00 2001 From: "Timur A. Fatkhullin" Date: Thu, 17 Apr 2025 11:58:54 +0300 Subject: [PATCH] ... --- cxx/mount.h | 76 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 68 insertions(+), 8 deletions(-) diff --git a/cxx/mount.h b/cxx/mount.h index ff863c7..7e1bb37 100644 --- a/cxx/mount.h +++ b/cxx/mount.h @@ -132,6 +132,29 @@ struct MccMountConfig { }; +/* PROHIBITED ZONE CONTEXT BASE CLASS */ +struct MccProhibitedZoneContext { + // type of prohibited zone + enum pzgeometry_t { + PZ_MINALT, // trivial minimal altitude + PZ_MAXALT, // trivial maximal altitude (e.g. near-zenith zone for alt-azimuthal types) + PZ_ELLIPSE, // simple circular/elliptical zone + PZ_PIER_MERIDIAN, // pier-side or cross-meridian + PZ_CONVEXHULL // general convex hull polygonal zone + }; + + // type of input cordinates + enum pzcoords_t { + PZCOORD_RADEC, // catalog (FK5, IRCS, etc...) + PZCOORD_RADEC_APP, // apparent RA and DEC + PZCOORD_HADEC_APP, // apparent HA and DEC + PZCOORD_AZZD, // apparent azimuth and zenithal distance + }; + + pzgeometry_t geometryType; + pzcoords_t coordType; +}; + /* MOUNT BASE TEMPLATED CLASS WITH BASIC FUNCTIONALITY */ // implements a Finite State Machine Pattern @@ -146,6 +169,12 @@ public: enum IersDatabaseType { IERS_DB_LEAPSECS, IERS_DB_EARTH_ORIENT }; + template + struct pzcheck_result_t { + bool inzone{false}; + DT time_to{DT::max()}; + DT time_from{DT::min()}; + }; /* Constructors and destructor */ @@ -301,20 +330,51 @@ public: return d_t{0}; } - // above two methods in one call - // returns a std::tuple with elements - // 0 - boolean: true - coordinates in zone, false - otherwise - // 1 - time duration to reach the zone (0 - if already in the zone, chrono::duration<>::max() if never reach the - // zone) - // 2 - time duration to exit the zone (0 - if already out of the zone, chrono::duration<>::max() if never - // exit the zone) + // returns a pzcheck_result_t with: + // .inzone = true - coordinates in zone, false - otherwise + // .time_to = time duration to reach the zone (0 - if already in the zone, chrono::duration<>::max() if never + // reach the zone) + // .time_from = time duration to exit the zone (0 - if already out of the zone, chrono::duration<>::max() if + // never exit the zone) + auto pzCheck(const MccCoordinate& xcoord, const MccCoordinate& ycoord, + std::derived_from auto const& context, traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now()) { using d_t = std::remove_cvref_t::duration; - return std::make_tuple(false, d_t::max(), d_t{0}); + return pzcheck_result_t{.inzone = false, .time_to = d_t::max(), .time_from = d_t{0}}; + } + + // template OR, std::ranges::input_range R1, std::ranges::input_range + // R2> + template + auto pzCheckRange(const R1& xcoord, + const R2& ycoord, + std::derived_from auto const& context) + requires(std::ranges::output_range> && + std::derived_from, MccCoordinate> && + std::derived_from, MccCoordinate>) + { + OR res; + + for (auto const& [c1, c2] : std::views::zip(xcoord, ycoord)) { + auto r = pzCheck(c1, c2, context); + std::back_inserter(res) = r; + } + + return res; + } + + template + auto pzCheckRange(const R1& xcoord, + const R2& ycoord, + std::derived_from auto const& context) + requires(std::derived_from, MccCoordinate> && + std::derived_from, MccCoordinate>) + { + return pzCheckRange>>(xcoord, ycoord, context); } // IERS databases updater