[geometry] fixed issue (found myself with testcase #buffer_mp1) where two specific circle-like polygons were not overlayed correctly. This was caused by sections not containing all points. We now make the section boxes a little smaller, such that they are not disjoint (10 * epsilon). This margin is a little fuzzy, but that is not harmful, they only influence might be some more comparisons. But that is intentional, we missed now one.

[SVN r83474]
This commit is contained in:
Barend Gehrels
2013-03-17 16:26:34 +00:00
parent 6ffb28d6ae
commit c992eb61e8
2 changed files with 39 additions and 0 deletions

View File

@@ -498,6 +498,29 @@ inline void set_section_unique_ids(Sections& sections)
}
}
template <typename Sections>
inline void enlargeSections(Sections& sections)
{
// Robustness issue. Increase sections a tiny bit such that all points are really within (and not on border)
// Reason: turns might, rarely, be missed otherwise (case: "buffer_mp1")
// Drawback: not really, range is now completely inside the section. Section is a tiny bit too large,
// which might cause (a small number) of more comparisons
// TODO: make dimension-agnostic
for (typename boost::range_iterator<Sections>::type it = boost::begin(sections);
it != boost::end(sections);
++it)
{
typedef typename boost::range_value<Sections>::type section_type;
typedef typename section_type::box_type box_type;
typedef typename geometry::coordinate_type<box_type>::type coordinate_type;
coordinate_type const reps = math::relaxed_epsilon(10.0);
geometry::set<0, 0>(it->bounding_box, geometry::get<0, 0>(it->bounding_box) - reps);
geometry::set<0, 1>(it->bounding_box, geometry::get<0, 1>(it->bounding_box) - reps);
geometry::set<1, 0>(it->bounding_box, geometry::get<1, 0>(it->bounding_box) + reps);
geometry::set<1, 1>(it->bounding_box, geometry::get<1, 1>(it->bounding_box) + reps);
}
}
}} // namespace detail::sectionalize
#endif // DOXYGEN_NO_DETAIL
@@ -639,6 +662,7 @@ inline void sectionalize(Geometry const& geometry, Sections& sections, int sourc
ring_id.source_index = source_index;
sectionalizer_type::apply(geometry, sections, ring_id);
detail::sectionalize::set_section_unique_ids(sections);
detail::sectionalize::enlargeSections(sections);
}

View File

@@ -102,6 +102,15 @@ struct define_pi
}
};
template <typename T>
struct relaxed_epsilon
{
static inline T apply(const T& factor)
{
return factor * std::numeric_limits<T>::epsilon();
}
};
} // namespace detail
#endif
@@ -110,6 +119,12 @@ struct define_pi
template <typename T>
inline T pi() { return detail::define_pi<T>::apply(); }
template <typename T>
inline T relaxed_epsilon(T const& factor)
{
return detail::relaxed_epsilon<T>::apply(factor);
}
// Maybe replace this by boost equals or boost ublas numeric equals or so