This commit is contained in:
Timur A. Fatkhullin 2025-04-18 12:15:32 +03:00
parent 78e1a7d71d
commit 3205db3ee1
4 changed files with 164 additions and 11 deletions

View File

@ -137,6 +137,7 @@ if (WITH_TESTS)
add_executable(${CFGFILE_TEST_APP} tests/configfile_test.cpp)
set(ASTROM_TEST_APP astrom_test)
add_executable(${ASTROM_TEST_APP} tests/astrom_test.cpp)
add_executable(${ASTROM_TEST_APP} tests/astrom_test.cpp
mount_pz.h)
target_link_libraries(${ASTROM_TEST_APP} ERFA_LIB)
endif()

View File

@ -129,15 +129,26 @@ public:
return sexagesimal<std::string>(hms, prec);
}
friend MccCoordinate operator+(const MccCoordinate& left, const MccCoordinate& right)
friend MccCoordinate operator+(std::convertible_to<MccCoordinate> auto&& left,
std::convertible_to<MccCoordinate> auto&& right)
{
return left._angleInRads + right._angleInRads;
return std::forward<decltype(left)>(left)._angleInRads + std::forward<decltype(right)>(right)._angleInRads;
}
// friend MccCoordinate operator+(const MccCoordinate& left, const MccCoordinate& right)
// {
// return left._angleInRads + right._angleInRads;
// }
friend MccCoordinate operator-(const MccCoordinate& left, const MccCoordinate& right)
friend MccCoordinate operator-(std::convertible_to<MccCoordinate> auto&& left,
std::convertible_to<MccCoordinate> auto&& right)
{
return left._angleInRads + right._angleInRads;
return std::forward<decltype(left)>(left)._angleInRads - std::forward<decltype(right)>(right)._angleInRads;
}
// friend MccCoordinate operator-(const MccCoordinate& left, const MccCoordinate& right)
// {
// return left._angleInRads + right._angleInRads;
// }
template <typename T>
MccCoordinate operator*(T&& scalar)
@ -187,6 +198,26 @@ public:
_angleInRads /= scalar;
return *this;
}
auto operator<=>(const MccCoordinate& other) const
{
return _angleInRads <=> other._angleInRads;
}
auto operator==(const MccCoordinate& other) const
{
return _angleInRads == other._angleInRads;
}
auto operator<=>(double other) const
{
return _angleInRads <=> other;
}
auto operator==(double other) const
{
return _angleInRads == other;
}
};

View File

@ -155,6 +155,28 @@ struct MccProhibitedZoneContext {
pzcoords_t coordType;
};
struct MccProhibitedZone1 {
// type of prohibited zone
enum pztype_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
};
pztype_t type;
struct pzminalt_t {
double minalt{0.0};
};
union {
} geometry;
};
/* MOUNT BASE TEMPLATED CLASS WITH BASIC FUNCTIONALITY */
// implements a Finite State Machine Pattern
@ -337,18 +359,15 @@ public:
// .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,
auto pzCheck(this auto&& self,
const MccCoordinate& xcoord,
const MccCoordinate& ycoord,
std::derived_from<MccProhibitedZoneContext> auto const& context,
traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
{
using d_t = std::remove_cvref_t<decltype(utc)>::duration;
return pzcheck_result_t<d_t>{.inzone = false, .time_to = d_t::max(), .time_from = d_t{0}};
return std::forward<decltype(self)>(self).pzCheckImpl(xcoord, ycoord, context, utc);
}
// template <std::ranges::output_range<pzcheck_result_t> OR, std::ranges::input_range R1, std::ranges::input_range
// R2>
template <std::ranges::range OR, std::ranges::input_range R1, std::ranges::input_range R2>
auto pzCheckRange(const R1& xcoord,
const R2& ycoord,
@ -424,6 +443,17 @@ protected:
std::atomic<MccMountSiteInfo> _geoLocation;
std::atomic<MccMountMeteo> _currentMeteo;
// default implementation
auto pzCheckImpl(const MccCoordinate& xcoord,
const MccCoordinate& ycoord,
std::derived_from<MccProhibitedZoneContext> auto const& context,
traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
{
using d_t = std::remove_cvref_t<decltype(utc)>::duration;
return pzcheck_result_t<d_t>{.inzone = false, .time_to = d_t::max(), .time_from = d_t{0}};
}
};
} // namespace mcc

91
cxx/mount_pz.h Normal file
View File

@ -0,0 +1,91 @@
#pragma once
#include "mcc_coord.h"
namespace mcc
{
class MccProhibitedZone
{
public:
virtual ~MccProhibitedZone() = default;
bool inZone(this auto&& self, const MccCoordinate& x, const MccCoordinate& y)
{
return std::forward<decltype(self)>(self).inZoneImpl(x, y);
}
protected:
bool inZoneImpl(const MccCoordinate&, const MccCoordinate&)
{
return false;
}
};
class MccMinAltPZ : public MccProhibitedZone
{
public:
MccMinAltPZ(const MccCoordinate& min_alt) : _minAlt(min_alt) {}
MccCoordinate minAlt() const
{
return _minAlt;
}
private:
double _minAlt;
bool inZoneImpl(const MccCoordinate& alt, const MccCoordinate&)
{
return alt <= _minAlt;
}
};
class MccMaxAltPZ
{
public:
MccMaxAltPZ(double max_alt) : _maxAlt(max_alt) {}
double maxAlt() const
{
return _maxAlt;
}
private:
double _maxAlt;
bool inZoneImpl(const MccCoordinate& alt, const MccCoordinate&)
{
return alt >= _maxAlt;
}
};
class MccElliipsePZ
{
public:
MccElliipsePZ(const MccCoordinate& xc, const MccCoordinate& yc, const MccCoordinate& a, const MccCoordinate& b)
: _xc(xc), _yc(yc), _a(a), _b(b), _a2(a * a), _b2(b * b)
{
}
// circle
MccElliipsePZ(const MccCoordinate& xc, const MccCoordinate& yc, const MccCoordinate& a)
: mcc::MccElliipsePZ(xc, yc, a, a)
{
}
private:
double _xc, _yc, _a, _b, _a2, _b2;
bool inZoneImpl(const MccCoordinate& alt, const MccCoordinate& zd)
{
auto x2 = alt - _xc;
auto y2 = zd - _yc;
return (x2 * x2 / _a2 + y2 * y2 / _b2) <= 1.0;
}
};
} // namespace mcc