File indexing completed on 2025-09-17 08:30:44
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_HAS_SELF_INTERSECTIONS_HPP
0016 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_HAS_SELF_INTERSECTIONS_HPP
0017
0018 #include <deque>
0019
0020 #include <boost/range/begin.hpp>
0021 #include <boost/range/end.hpp>
0022 #include <boost/throw_exception.hpp>
0023
0024 #include <boost/geometry/core/point_type.hpp>
0025 #include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
0026 #include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
0027 #include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp>
0028
0029 #include <boost/geometry/policies/disjoint_interrupt_policy.hpp>
0030
0031 #ifdef BOOST_GEOMETRY_DEBUG_HAS_SELF_INTERSECTIONS
0032 # include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
0033 # include <boost/geometry/io/dsv/write.hpp>
0034 #endif
0035
0036
0037 namespace boost { namespace geometry
0038 {
0039
0040
0041 #if ! defined(BOOST_GEOMETRY_OVERLAY_NO_THROW)
0042
0043
0044
0045
0046
0047
0048 class overlay_invalid_input_exception : public geometry::exception
0049 {
0050 public:
0051
0052 inline overlay_invalid_input_exception() {}
0053
0054 char const* what() const noexcept override
0055 {
0056 return "Boost.Geometry Overlay invalid input exception";
0057 }
0058 };
0059
0060 #endif
0061
0062
0063 #ifndef DOXYGEN_NO_DETAIL
0064 namespace detail { namespace overlay
0065 {
0066
0067
0068 template <typename Geometry, typename Strategy>
0069 inline bool has_self_intersections(Geometry const& geometry,
0070 Strategy const& strategy,
0071 bool throw_on_self_intersection = true)
0072 {
0073 using point_type = point_type_t<Geometry>;
0074 using turn_info = turn_info
0075 <
0076 point_type,
0077 typename segment_ratio_type<point_type>::type
0078 >;
0079 std::deque<turn_info> turns;
0080 detail::disjoint::disjoint_interrupt_policy policy;
0081
0082 detail::self_get_turn_points::self_turns
0083 <
0084 false,
0085 detail::overlay::assign_null_policy
0086 >(geometry, strategy, turns, policy, 0, false);
0087
0088 #ifdef BOOST_GEOMETRY_DEBUG_HAS_SELF_INTERSECTIONS
0089 bool first = true;
0090 #endif
0091 for (auto const& info : turns)
0092 {
0093 bool const both_union_turn =
0094 info.operations[0].operation == detail::overlay::operation_union
0095 && info.operations[1].operation == detail::overlay::operation_union;
0096 bool const both_intersection_turn =
0097 info.operations[0].operation == detail::overlay::operation_intersection
0098 && info.operations[1].operation == detail::overlay::operation_intersection;
0099
0100 bool const valid = (both_union_turn || both_intersection_turn)
0101 && (info.method == detail::overlay::method_touch
0102 || info.method == detail::overlay::method_touch_interior);
0103
0104 if (! valid)
0105 {
0106 #ifdef BOOST_GEOMETRY_DEBUG_HAS_SELF_INTERSECTIONS
0107 if (first)
0108 {
0109 std::cout << "turn points: " << std::endl;
0110 first = false;
0111 }
0112 std::cout << method_char(info.method);
0113 for (int i = 0; i < 2; i++)
0114 {
0115 std::cout << " " << operation_char(info.operations[i].operation);
0116 std::cout << " " << info.operations[i].seg_id;
0117 }
0118 std::cout << " " << geometry::dsv(info.point) << std::endl;
0119 #endif
0120
0121 #if ! defined(BOOST_GEOMETRY_OVERLAY_NO_THROW)
0122 if (throw_on_self_intersection)
0123 {
0124 BOOST_THROW_EXCEPTION(overlay_invalid_input_exception());
0125 }
0126 #endif
0127 return true;
0128 }
0129
0130 }
0131 return false;
0132 }
0133
0134
0135 }}
0136 #endif
0137
0138
0139 }}
0140
0141
0142 #endif
0143