mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-10 11:32:15 +00:00
[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:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user