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/is_simple
This commit is contained in:
@@ -273,6 +273,15 @@ struct segments_direction
|
||||
return return_type('0', false);
|
||||
}
|
||||
|
||||
template <typename Segment, typename Ratio>
|
||||
static inline return_type one_degenerate(Segment const& ,
|
||||
Ratio const& ,
|
||||
bool)
|
||||
{
|
||||
// To be decided
|
||||
return return_type('0', false);
|
||||
}
|
||||
|
||||
static inline return_type disjoint()
|
||||
{
|
||||
return return_type('d', false);
|
||||
|
||||
@@ -189,6 +189,7 @@ struct segments_intersection_points
|
||||
return return_type();
|
||||
}
|
||||
|
||||
// Both degenerate
|
||||
template <typename Segment>
|
||||
static inline return_type degenerate(Segment const& segment, bool)
|
||||
{
|
||||
@@ -198,6 +199,27 @@ struct segments_intersection_points
|
||||
set<1>(result.intersections[0], get<0, 1>(segment));
|
||||
return result;
|
||||
}
|
||||
|
||||
// One degenerate
|
||||
template <typename Segment, typename Ratio>
|
||||
static inline return_type one_degenerate(Segment const& degenerate_segment,
|
||||
Ratio const& ratio, bool a_degenerate)
|
||||
{
|
||||
return_type result;
|
||||
result.count = 1;
|
||||
set<0>(result.intersections[0], get<0, 0>(degenerate_segment));
|
||||
set<1>(result.intersections[0], get<0, 1>(degenerate_segment));
|
||||
if (a_degenerate)
|
||||
{
|
||||
// IP lies on ratio w.r.t. segment b
|
||||
result.fractions[0].assign(Ratio::zero(), ratio);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.fractions[0].assign(ratio, Ratio::zero());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -68,6 +68,18 @@ struct segments_tupled
|
||||
);
|
||||
}
|
||||
|
||||
template <typename Segment, typename Ratio>
|
||||
static inline return_type one_degenerate(Segment const& segment,
|
||||
Ratio const& ratio,
|
||||
bool a_degenerate)
|
||||
{
|
||||
return boost::make_tuple
|
||||
(
|
||||
Policy1::one_degenerate(segment, ratio, a_degenerate),
|
||||
Policy2::one_degenerate(segment, ratio, a_degenerate)
|
||||
);
|
||||
}
|
||||
|
||||
static inline return_type disjoint()
|
||||
{
|
||||
return boost::make_tuple
|
||||
|
||||
@@ -144,16 +144,6 @@ struct relate_cartesian_segments
|
||||
return Policy::disjoint();
|
||||
}
|
||||
|
||||
// Degenerate cases: segments of single point, lying on other segment, are not disjoint
|
||||
if (a_is_point)
|
||||
{
|
||||
return Policy::degenerate(a, true);
|
||||
}
|
||||
if (b_is_point)
|
||||
{
|
||||
return Policy::degenerate(b, false);
|
||||
}
|
||||
|
||||
typedef typename select_most_precise
|
||||
<
|
||||
coordinate_type, double
|
||||
@@ -219,19 +209,27 @@ struct relate_cartesian_segments
|
||||
}
|
||||
}
|
||||
|
||||
if(collinear)
|
||||
if (collinear)
|
||||
{
|
||||
bool const collinear_use_first
|
||||
= geometry::math::abs(robust_dx_a) + geometry::math::abs(robust_dx_b)
|
||||
>= geometry::math::abs(robust_dy_a) + geometry::math::abs(robust_dy_b);
|
||||
|
||||
// Degenerate cases: segments of single point, lying on other segment, are not disjoint
|
||||
// This situation is collinear too
|
||||
|
||||
if (collinear_use_first)
|
||||
{
|
||||
return relate_collinear<0, ratio_type>(a, b, robust_a1, robust_a2, robust_b1, robust_b2);
|
||||
return relate_collinear<0, ratio_type>(a, b,
|
||||
robust_a1, robust_a2, robust_b1, robust_b2,
|
||||
a_is_point, b_is_point);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Y direction contains larger segments (maybe dx is zero)
|
||||
return relate_collinear<1, ratio_type>(a, b, robust_a1, robust_a2, robust_b1, robust_b2);
|
||||
return relate_collinear<1, ratio_type>(a, b,
|
||||
robust_a1, robust_a2, robust_b1, robust_b2,
|
||||
a_is_point, b_is_point);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,8 +248,23 @@ private:
|
||||
static inline return_type relate_collinear(Segment1 const& a,
|
||||
Segment2 const& b,
|
||||
RobustPoint const& robust_a1, RobustPoint const& robust_a2,
|
||||
RobustPoint const& robust_b1, RobustPoint const& robust_b2)
|
||||
RobustPoint const& robust_b1, RobustPoint const& robust_b2,
|
||||
bool a_is_point, bool b_is_point)
|
||||
{
|
||||
if (a_is_point)
|
||||
{
|
||||
return relate_one_degenerate<RatioType>(a,
|
||||
get<Dimension>(robust_a1),
|
||||
get<Dimension>(robust_b1), get<Dimension>(robust_b2),
|
||||
true);
|
||||
}
|
||||
if (b_is_point)
|
||||
{
|
||||
return relate_one_degenerate<RatioType>(b,
|
||||
get<Dimension>(robust_b1),
|
||||
get<Dimension>(robust_a1), get<Dimension>(robust_a2),
|
||||
false);
|
||||
}
|
||||
return relate_collinear<RatioType>(a, b,
|
||||
get<Dimension>(robust_a1),
|
||||
get<Dimension>(robust_a2),
|
||||
@@ -318,6 +331,28 @@ private:
|
||||
|
||||
return Policy::segments_collinear(a, b, ra_from, ra_to, rb_from, rb_to);
|
||||
}
|
||||
|
||||
/// Relate segments where one is degenerate
|
||||
template
|
||||
<
|
||||
typename RatioType,
|
||||
typename DegenerateSegment,
|
||||
typename RobustType
|
||||
>
|
||||
static inline return_type relate_one_degenerate(
|
||||
DegenerateSegment const& degenerate_segment
|
||||
, RobustType d
|
||||
, RobustType s1, RobustType s2
|
||||
, bool a_degenerate
|
||||
)
|
||||
{
|
||||
// Calculate the ratios where ds starts in s
|
||||
// a1--------->a2 (2..6)
|
||||
// b1/b2 (4..4)
|
||||
// Ratio: (4-2)/(6-2)
|
||||
RatioType const ratio(d - s1, s2 - s1);
|
||||
return Policy::one_degenerate(degenerate_segment, ratio, a_degenerate);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -230,14 +230,16 @@ void test_all()
|
||||
// to_svg<ls, ls>("LINESTRING(31 0,15 0,10 5,5 5,4 0,1 0,0 0,-1 1)", "LINESTRING(30 0,3 0,2.5 1,2 0,1 0,0 0,-1 -1)", "test34.svg");
|
||||
//}
|
||||
|
||||
// duplicated
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 0,10 0,30 0))",
|
||||
"MULTILINESTRING((0 10,5 0,20 0,20 0,30 0),(2 0,2 0),(3 0,3 0,3 0))",
|
||||
expected("mii")("ccc")("ccc")("txx"));
|
||||
|
||||
// spike
|
||||
test_geometry<ls, ls>("LINESTRING(2 2,5 -1,15 2,18 0,20 0)",
|
||||
"LINESTRING(30 0,19 0,18 0,0 0)",
|
||||
expected("iuu")("iuu")("tiu")("mxi"));
|
||||
|
||||
// spike
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 0,10 0,5 0))",
|
||||
"MULTILINESTRING((1 0,8 0,4 0))",
|
||||
expected("mii")("mix")("mux")("mui")("mix")("mii")("mxu")("mxi"));
|
||||
@@ -245,6 +247,24 @@ void test_all()
|
||||
/*test_geometry<mls, mls>("MULTILINESTRING((0 0,10 0,5 0))",
|
||||
"MULTILINESTRING((1 0,8 0,4 0),(2 0,9 0,5 0))",
|
||||
expected("mii")("ccc")("ccc")("txx"));*/
|
||||
|
||||
// spike vs endpoint
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 0,10 0))",
|
||||
"MULTILINESTRING((-1 0,0 0,-2 0),(11 0,10 0,12 0))",
|
||||
expected("tuu")("txu"));
|
||||
// non-spike similar
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 0,10 0))",
|
||||
"MULTILINESTRING((-1 0,0 0,2 0))",
|
||||
expected("tii")("mux"));
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 0,10 0))",
|
||||
"MULTILINESTRING((-1 -1,0 0,2 0))",
|
||||
expected("tii")("mux"));
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 0,10 0))",
|
||||
"MULTILINESTRING((2 0,0 0,-1 0))",
|
||||
expected("tiu")("mui"));
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 0,10 0))",
|
||||
"MULTILINESTRING((2 0,0 0,-1 -1))",
|
||||
expected("tiu")("mui"));
|
||||
}
|
||||
|
||||
int test_main(int, char* [])
|
||||
|
||||
@@ -118,7 +118,8 @@ static void test_segment_ratio(std::string const& case_id,
|
||||
int x3, int y3, int x4, int y4,
|
||||
Pair expected_pair_a1, Pair expected_pair_a2,
|
||||
Pair expected_pair_b1, Pair expected_pair_b2,
|
||||
int exp_ax1, int exp_ay1, int exp_ax2, int exp_ay2)
|
||||
int exp_ax1, int exp_ay1, int exp_ax2, int exp_ay2,
|
||||
std::size_t expected_count = 2)
|
||||
|
||||
{
|
||||
boost::ignore_unused_variable_warning(case_id);
|
||||
@@ -157,16 +158,20 @@ static void test_segment_ratio(std::string const& case_id,
|
||||
ratio_type expected_b1(expected_pair_b1.first, expected_pair_b1.second);
|
||||
ratio_type expected_b2(expected_pair_b2.first, expected_pair_b2.second);
|
||||
|
||||
BOOST_CHECK_EQUAL(is.count, 2u);
|
||||
BOOST_CHECK_EQUAL(is.fractions[0].robust_ra, expected_a1);
|
||||
BOOST_CHECK_EQUAL(is.fractions[1].robust_ra, expected_a2);
|
||||
BOOST_CHECK_EQUAL(is.fractions[0].robust_rb, expected_b1);
|
||||
BOOST_CHECK_EQUAL(is.fractions[1].robust_rb, expected_b2);
|
||||
BOOST_CHECK_EQUAL(is.count, expected_count);
|
||||
|
||||
BOOST_CHECK_EQUAL(is.fractions[0].robust_ra, expected_a1);
|
||||
BOOST_CHECK_EQUAL(is.fractions[0].robust_rb, expected_b1);
|
||||
BOOST_CHECK_EQUAL(bg::get<0>(is.intersections[0]), exp_ax1);
|
||||
BOOST_CHECK_EQUAL(bg::get<1>(is.intersections[0]), exp_ay1);
|
||||
BOOST_CHECK_EQUAL(bg::get<0>(is.intersections[1]), exp_ax2);
|
||||
BOOST_CHECK_EQUAL(bg::get<1>(is.intersections[1]), exp_ay2);
|
||||
|
||||
if (expected_count == 2)
|
||||
{
|
||||
BOOST_CHECK_EQUAL(bg::get<0>(is.intersections[1]), exp_ax2);
|
||||
BOOST_CHECK_EQUAL(bg::get<1>(is.intersections[1]), exp_ay2);
|
||||
BOOST_CHECK_EQUAL(is.fractions[1].robust_ra, expected_a2);
|
||||
BOOST_CHECK_EQUAL(is.fractions[1].robust_rb, expected_b2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -487,6 +492,30 @@ void test_ratios()
|
||||
std::make_pair(0, 1), std::make_pair(1, 3),
|
||||
5, 0, 6, 0);
|
||||
|
||||
// Degenerated one
|
||||
// a1---------->a2
|
||||
// b1/b2
|
||||
const int ignored = 99;
|
||||
test_segment_ratio<P>("degenerated1",
|
||||
2, 0, 6, 0,
|
||||
5, 0, 5, 0,
|
||||
std::make_pair(3, 4), // IP located on 3/4 w.r.t A
|
||||
std::make_pair(ignored, 1), // not checked
|
||||
std::make_pair(0, 1), // IP located at any place w.r.t B, so 0
|
||||
std::make_pair(ignored, 1), // not checked
|
||||
5, 0,
|
||||
ignored, ignored,
|
||||
1);
|
||||
|
||||
test_segment_ratio<P>("degenerated2",
|
||||
5, 0, 5, 0,
|
||||
2, 0, 6, 0,
|
||||
std::make_pair(0, 1), std::make_pair(ignored, 1),
|
||||
std::make_pair(3, 4), std::make_pair(ignored, 1),
|
||||
5, 0,
|
||||
ignored, ignored,
|
||||
1);
|
||||
|
||||
// Vertical one like in box_poly5 but in integer
|
||||
test_segment_ratio<P>("box_poly5",
|
||||
45, 25, 45, 15,
|
||||
|
||||
Reference in New Issue
Block a user