/* Copyright 2012 Lucanus Simonson Use, modification and distribution are subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt). */ #ifndef BOOST_POLYGON_SEGMENT_UTILS_HPP #define BOOST_POLYGON_SEGMENT_UTILS_HPP #include #include #include #include "detail/scan_arbitrary.hpp" #include "isotropy.hpp" #include "rectangle_concept.hpp" #include "segment_concept.hpp" namespace boost { namespace polygon { template typename enable_if< typename gtl_and< typename gtl_if< typename is_segment_concept< typename geometry_concept< typename std::iterator_traits::value_type >::type >::type >::type, typename gtl_if< typename is_segment_concept< typename geometry_concept::type >::type >::type >::type, void >::type intersect_segments( std::vector >& result, SegmentIterator first, SegmentIterator last) { typedef typename segment_traits::coordinate_type Unit; typedef typename scanline_base::Point Point; typedef typename scanline_base::half_edge half_edge; typedef int segment_id; std::vector > half_edges; std::vector > half_edges_out; segment_id id_in = 0; half_edges.reserve(std::distance(first, last)); for (; first != last; ++first) { Point l, h; assign(l, low(*first)); assign(h, high(*first)); half_edges.push_back(std::make_pair(half_edge(l, h), id_in++)); } half_edges_out.reserve(half_edges.size()); // Apparently no need to pre-sort data when calling validate_scan. if (half_edges.size() != 0) { line_intersection::validate_scan( half_edges_out, half_edges.begin(), half_edges.end()); } result.reserve(result.size() + half_edges_out.size()); for (std::size_t i = 0; i < half_edges_out.size(); ++i) { std::size_t id = (std::size_t)(half_edges_out[i].second); Point l = half_edges_out[i].first.first; Point h = half_edges_out[i].first.second; result.push_back(std::make_pair(id, construct(l, h))); } } template typename enable_if< typename gtl_and< typename gtl_if< typename is_segment_concept< typename geometry_concept< typename std::iterator_traits::value_type >::type >::type >::type, typename gtl_if< typename is_segment_concept< typename geometry_concept< typename SegmentContainer::value_type >::type >::type >::type >::type, void >::type intersect_segments( SegmentContainer& result, SegmentIterator first, SegmentIterator last) { typedef typename SegmentContainer::value_type segment_type; typedef typename segment_traits::coordinate_type Unit; typedef typename scanline_base::Point Point; typedef typename scanline_base::half_edge half_edge; typedef int segment_id; std::vector > half_edges; std::vector > half_edges_out; segment_id id_in = 0; half_edges.reserve(std::distance(first, last)); for (; first != last; ++first) { Point l, h; assign(l, low(*first)); assign(h, high(*first)); half_edges.push_back(std::make_pair(half_edge(l, h), id_in++)); } half_edges_out.reserve(half_edges.size()); // Apparently no need to pre-sort data when calling validate_scan. if (half_edges.size() != 0) { line_intersection::validate_scan( half_edges_out, half_edges.begin(), half_edges.end()); } result.reserve(result.size() + half_edges_out.size()); for (std::size_t i = 0; i < half_edges_out.size(); ++i) { Point l = half_edges_out[i].first.first; Point h = half_edges_out[i].first.second; result.push_back(construct(l, h)); } } template typename enable_if< typename gtl_and< typename gtl_if< typename is_rectangle_concept< typename geometry_concept::type >::type >::type, typename gtl_if< typename is_segment_concept< typename geometry_concept< typename std::iterator_traits::value_type >::type >::type >::type >::type, bool >::type envelope_segments( Rectangle& rect, SegmentIterator first, SegmentIterator last) { for (SegmentIterator it = first; it != last; ++it) { if (it == first) { set_points(rect, low(*it), high(*it)); } else { encompass(rect, low(*it)); encompass(rect, high(*it)); } } return first != last; } } // polygon } // boost #endif // BOOST_POLYGON_SEGMENT_UTILS_HPP