mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-13 00:22:10 +00:00
Merge branch 'develop' of https://github.com/boostorg/geometry into feature/shortest_points_new_strategies
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user