1
// Generic Geometry Library
3
// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
4
// Copyright Bruno Lalande 2008, 2009
5
// Use, modification and distribution is subject to the Boost Software License,
6
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7
// http://www.boost.org/LICENSE_1_0.txt)
9
#ifndef GGL_ALGORITHMS_MERGE_INTERSECTION_POINTS_HPP
10
#define GGL_ALGORITHMS_MERGE_INTERSECTION_POINTS_HPP
15
#include <boost/range/functions.hpp>
16
#include <boost/range/metafunctions.hpp>
19
#include <ggl/core/coordinate_type.hpp>
21
#include <ggl/algorithms/equals.hpp>
28
#ifndef DOXYGEN_NO_DETAIL
29
namespace detail { namespace intersection {
31
template <typename PointType>
32
struct on_increasing_dimension
34
typedef typename ggl::coordinate_type<PointType>::type coordinate_type;
36
inline bool operator()(PointType const& lhs, PointType const& rhs) const
38
coordinate_type const& left0 = ggl::get<0>(lhs);
39
coordinate_type const& right0 = ggl::get<0>(rhs);
41
return math::equals(left0, right0)
42
? ggl::get<1>(lhs) < ggl::get<1>(rhs)
51
inline bool operator()(T const& object) const
53
typedef typename T::traversal_vector tv;
54
typedef typename boost::range_const_iterator<tv>::type tvit_type;
55
for (tvit_type it = boost::begin(object.info);
56
it != boost::end(object.info); ++it)
58
// If not collinear / not "TO", do NOT delete (false)
59
if (it->how != 'c' && it->how != 't' && it->how != 'm')
70
template <typename T, int Index>
73
inline bool operator()(T const& object) const
75
return object.shared_code == Index;
80
}} // namespace detail::intersection
81
#endif //DOXYGEN_NO_DETAIL
86
inline void merge_intersection_points(V& intersection_points)
88
typedef typename boost::range_value<V>::type trav_type;
90
// Remove all IP's which are collinear
91
intersection_points.erase(
93
boost::begin(intersection_points),
94
boost::end(intersection_points),
95
detail::intersection::is_collinear<trav_type>()),
96
boost::end(intersection_points));
98
if (intersection_points.size() <= 1)
104
// Sort all IP's from left->right, ymin->ymax such that
105
// all same IP's are consecutive
106
// (and we need this order lateron again)
107
// This order is NOT changed here and should not be after
108
// (otherwise indexes are wrong)
109
std::sort(boost::begin(intersection_points),
110
boost::end(intersection_points),
111
detail::intersection::on_increasing_dimension<trav_type>());
113
typedef typename boost::range_iterator<V>::type iterator;
115
#ifdef GGL_DEBUG_INTERSECTION
116
std::cout << "Sorted (x then y): " << std::endl;
117
for (iterator it = boost::begin(intersection_points);
118
it != boost::end(intersection_points); ++it)
123
bool has_merge = false;
125
// Merge all same IP's, combining there IP/segment-info entries
126
iterator it = boost::begin(intersection_points);
127
for (iterator prev = it++; it != boost::end(intersection_points); ++it)
129
// IP can be merged if the point is equal
130
if (ggl::equals(prev->point, it->point))
133
prev->shared_code = 1;
135
std::copy(it->info.begin(), it->info.end(),
136
std::back_inserter(prev->info));
147
// Remove all IP's which are merged (code=2)
148
intersection_points.erase(
150
boost::begin(intersection_points),
151
boost::end(intersection_points),
152
detail::intersection::shared_code_is<trav_type, 2>()),
153
boost::end(intersection_points));
156
#ifdef GGL_DEBUG_INTERSECTION
157
std::cout << "Merged: " << std::endl;
158
for (iterator it = boost::begin(intersection_points);
159
it != boost::end(intersection_points);
170
#endif // GGL_ALGORITHMS_MERGE_INTERSECTION_POINTS_HPP