Merge branch 'develop' of https://github.com/boostorg/geometry into feature/shortest_points_new_strategies

This commit is contained in:
Vissarion Fisikopoulos
2021-10-06 14:35:06 +03:00
20 changed files with 262 additions and 34 deletions

View File

@@ -175,7 +175,7 @@ public:
// unit tests of hard cases start to fail (5 in multi_polygon)
// But it is acknowlegded that such a threshold depends on the
// scale of the input.
if (state.m_min_distance > 1.0e-5 || ! state.m_close_to_offset)
if (state.m_min_distance > 1.0e-4 || ! state.m_close_to_offset)
{
Turn& mutable_turn = m_turns[turn.turn_index];
mutable_turn.is_turn_traversable = false;

View File

@@ -79,7 +79,8 @@ struct direction_code_impl<cartesian_tag>
}
calc_t const sv = arithmetic::side_value(line, point);
return sv == 0 ? 0 : sv > 0 ? 1 : -1;
static calc_t const zero = 0;
return sv == zero ? 0 : sv > zero ? 1 : -1;
}
};

View File

@@ -23,7 +23,7 @@ namespace detail { namespace overlay
template <typename Point1, typename Point2, typename E>
inline bool approximately_equals(Point1 const& a, Point2 const& b,
E const& multiplier)
E const& epsilon_multiplier)
{
using coor_t = typename select_coordinate_type<Point1, Point2>::type;
using calc_t = typename geometry::select_most_precise<coor_t, E>::type;
@@ -34,7 +34,7 @@ inline bool approximately_equals(Point1 const& a, Point2 const& b,
calc_t const& b1 = geometry::get<1>(b);
math::detail::equals_factor_policy<calc_t> policy(a0, b0, a1, b1);
policy.factor *= multiplier;
policy.multiply_epsilon(epsilon_multiplier);
return math::detail::equals_by_policy(a0, b0, policy)
&& math::detail::equals_by_policy(a1, b1, policy);

View File

@@ -39,7 +39,8 @@ struct sweep_equal_policy
static inline bool equals(P const& p1, P const& p2)
{
// Points within a kilo epsilon are considered as equal
return approximately_equals(p1, p2, 1000.0);
using coor_t = typename coordinate_type<P>::type;
return approximately_equals(p1, p2, coor_t(1000));
}
template <typename T>
@@ -47,7 +48,8 @@ struct sweep_equal_policy
{
// This threshold is an arbitrary value
// as long as it is than the used kilo-epsilon
return value > 1.0e-3;
T const limit = T(1) / T(1000);
return value > limit;
}
};

View File

@@ -128,7 +128,8 @@ struct base_turn_handler
}
auto const dm = get_distance_measure(range_p.at(range_index), range_p.at(range_index + 1), range_q.at(point_index));
return dm.measure == 0 ? 0 : dm.measure > 0 ? 1 : -1;
static decltype(dm.measure) const zero = 0;
return dm.measure == zero ? 0 : dm.measure > zero ? 1 : -1;
}
template

View File

@@ -316,7 +316,15 @@ public :
// then take a point (or more) further back.
// The limit of offset avoids theoretical infinite loops.
// In practice it currently walks max 1 point back in all cases.
double const tolerance = 1.0e9;
// Use the coordinate type, but if it is too small (e.g. std::int16), use a double
using ct_type = typename geometry::select_most_precise
<
typename geometry::coordinate_type<Point>::type,
double
>::type;
ct_type const tolerance = 1000000000;
int offset = 0;
while (approximately_equals(point_from, turn.point, tolerance)
&& offset > -10)

View File

@@ -783,22 +783,24 @@ inline void enlarge_sections(Sections& sections, Strategy const&)
// It makes section a tiny bit too large, which might cause (a small number)
// of more comparisons
for (typename boost::range_iterator<Sections>::type it = boost::begin(sections);
it != boost::end(sections);
++it)
for (auto& section : sections)
{
#if defined(BOOST_GEOMETRY_USE_RESCALING)
detail::sectionalize::expand_by_epsilon
<
typename Strategy::cs_tag
>::apply(it->bounding_box);
>::apply(section.bounding_box);
#else
// Expand the box to avoid missing any intersection. The amount is
// should be larger than epsilon. About the value itself: the smaller
// it is, the higher the risk to miss intersections. The larger it is,
// the more comparisons are made. So it should be on the high side.
detail::buffer::buffer_box(it->bounding_box, 0.001, it->bounding_box);
using gt = decltype(section.bounding_box);
using ct = typename geometry::coordinate_type<gt>::type;
ct const tolerance = ct(1) / ct(1000);
detail::buffer::buffer_box(section.bounding_box, tolerance,
section.bounding_box);
#endif
}
}

View File

@@ -119,7 +119,8 @@ struct possibly_collinear<Type, false>
template <typename Ratio, typename Threshold>
static inline bool apply(Ratio const& ratio, Threshold)
{
return ratio.denominator() == 0;
static Type const zero = 0;
return ratio.denominator() == zero;
}
};
@@ -216,14 +217,14 @@ public :
{
// Minimal normalization
// 1/-4 => -1/4, -1/-4 => 1/4
if (m_denominator < 0)
if (m_denominator < zero_instance())
{
m_numerator = -m_numerator;
m_denominator = -m_denominator;
}
m_approximation =
m_denominator == 0 ? 0
m_denominator == zero_instance() ? 0
: (
boost::numeric_cast<floating_point_type>(m_numerator) * scale()
/ boost::numeric_cast<floating_point_type>(m_denominator)
@@ -235,12 +236,12 @@ public :
inline bool on_segment() const
{
// e.g. 0/4 or 4/4 or 2/4
return m_numerator >= 0 && m_numerator <= m_denominator;
return m_numerator >= zero_instance() && m_numerator <= m_denominator;
}
inline bool in_segment() const
{
// e.g. 1/4
return m_numerator > 0 && m_numerator < m_denominator;
return m_numerator > zero_instance() && m_numerator < m_denominator;
}
inline bool on_end() const
{
@@ -250,7 +251,7 @@ public :
inline bool left() const
{
// e.g. -1/4
return m_numerator < 0;
return m_numerator < zero_instance();
}
inline bool right() const
{
@@ -336,6 +337,11 @@ private :
static floating_point_type const fp_scale{1000000.0};
return fp_scale;
}
static inline Type zero_instance()
{
return 0;
}
};

View File

@@ -87,7 +87,7 @@ public:
);
PromotedType const zero = PromotedType();
return sv == 0 ? 0 : sv > zero ? 1 : -1;
return sv == zero ? 0 : sv > zero ? 1 : -1;
}
};

View File

@@ -139,6 +139,12 @@ struct equals_factor_policy
return factor;
}
template <typename E>
void multiply_epsilon(E const& multiplier)
{
factor *= multiplier;
}
T factor;
};
@@ -153,6 +159,8 @@ struct equals_factor_policy<T, false>
{
return T(1);
}
void multiply_epsilon(T const& ) {}
};
template <typename Type,