123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- #ifndef BOOST_GEOMETRY_STRATEGY_CARTESIAN_SIDE_ROBUST_HPP
- #define BOOST_GEOMETRY_STRATEGY_CARTESIAN_SIDE_ROBUST_HPP
- #include <boost/geometry/core/config.hpp>
- #include <boost/geometry/strategy/cartesian/side_non_robust.hpp>
- #include <boost/geometry/strategies/side.hpp>
- #include <boost/geometry/util/select_most_precise.hpp>
- #include <boost/geometry/util/select_calculation_type.hpp>
- #include <boost/geometry/util/precise_math.hpp>
- #include <boost/geometry/util/math.hpp>
- namespace boost { namespace geometry
- {
- namespace strategy { namespace side
- {
- struct epsilon_equals_policy
- {
- public:
- template <typename Policy, typename T1, typename T2>
- static bool apply(T1 const& a, T2 const& b, Policy const& policy)
- {
- return boost::geometry::math::detail::equals_by_policy(a, b, policy);
- }
- };
- struct fp_equals_policy
- {
- public:
- template <typename Policy, typename T1, typename T2>
- static bool apply(T1 const& a, T2 const& b, Policy const&)
- {
- return a == b;
- }
- };
- template
- <
- typename CalculationType = void,
- typename EqualsPolicy = epsilon_equals_policy,
- std::size_t Robustness = 3
- >
- struct side_robust
- {
- template <typename CT>
- struct epsilon_policy
- {
- using Policy = boost::geometry::math::detail::equals_factor_policy<CT>;
- epsilon_policy() {}
- template <typename Type>
- epsilon_policy(Type const& a, Type const& b, Type const& c, Type const& d)
- : m_policy(a, b, c, d)
- {}
- Policy m_policy;
- public:
- template <typename T1, typename T2>
- bool apply(T1 a, T2 b) const
- {
- return EqualsPolicy::apply(a, b, m_policy);
- }
- };
- public:
- typedef cartesian_tag cs_tag;
-
- template
- <
- typename PromotedType,
- typename P1,
- typename P2,
- typename P,
- typename EpsPolicyInternal,
- std::enable_if_t<std::is_fundamental<PromotedType>::value, int> = 0
- >
- static inline PromotedType side_value(P1 const& p1,
- P2 const& p2,
- P const& p,
- EpsPolicyInternal& eps_policy)
- {
- using vec2d = ::boost::geometry::detail::precise_math::vec2d<PromotedType>;
- vec2d pa;
- pa.x = get<0>(p1);
- pa.y = get<1>(p1);
- vec2d pb;
- pb.x = get<0>(p2);
- pb.y = get<1>(p2);
- vec2d pc;
- pc.x = get<0>(p);
- pc.y = get<1>(p);
- return ::boost::geometry::detail::precise_math::orient2d
- <PromotedType, Robustness>(pa, pb, pc, eps_policy);
- }
- template
- <
- typename PromotedType,
- typename P1,
- typename P2,
- typename P,
- typename EpsPolicyInternal,
- std::enable_if_t<!std::is_fundamental<PromotedType>::value, int> = 0
- >
- static inline auto side_value(P1 const& p1, P2 const& p2, P const& p,
- EpsPolicyInternal&)
- {
- return side_non_robust<>::apply(p1, p2, p);
- }
- #ifndef DOXYGEN_SHOULD_SKIP_THIS
- template
- <
- typename P1,
- typename P2,
- typename P
- >
- static inline int apply(P1 const& p1, P2 const& p2, P const& p)
- {
- using coordinate_type = typename select_calculation_type_alt
- <
- CalculationType,
- P1,
- P2,
- P
- >::type;
- using promoted_type = typename select_most_precise
- <
- coordinate_type,
- double
- >::type;
- epsilon_policy<promoted_type> epsp;
- promoted_type sv = side_value<promoted_type>(p1, p2, p, epsp);
- promoted_type const zero = promoted_type();
- return epsp.apply(sv, zero) ? 0
- : sv > zero ? 1
- : -1;
- }
- #endif
- };
- }}
- }}
- #endif
|