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

This commit is contained in:
Menelaos Karavelas
2014-04-30 22:06:13 +03:00
6 changed files with 150 additions and 23 deletions

View File

@@ -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);

View File

@@ -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;
}
};

View File

@@ -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

View File

@@ -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);
}
};

View File

@@ -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* [])

View File

@@ -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,