1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <algorithm>
#include <ostream>
#include <sstream>
#include <string>
#include <vector>
#include <boost/config.hpp>
#include <geometry_test_common.hpp>
#include <boost/geometry/algorithms/correct.hpp>
#include <boost/geometry/algorithms/within.hpp>
#include <boost/geometry/algorithms/intersection_segment.hpp>
#include <boost/geometry/io/wkt/aswkt.hpp>
static std::ostream & operator<<(std::ostream &s, const bg::intersection_result& r)
{
switch(r)
{
case bg::is_intersect_no : s << "is_intersect_no"; break;
case bg::is_intersect : s << "is_intersect"; break;
case bg::is_parallel : s << "is_parallel"; break;
case bg::is_collinear_no : s << "is_collinear_no"; break;
case bg::is_collinear_one : s << "is_collinear_one"; break;
case bg::is_collinear_connect : s << "is_collinear_connect"; break;
case bg::is_collinear_overlap : s << "is_collinear_overlap"; break;
case bg::is_collinear_overlap_opposite : s << "is_collinear_overlap_opposite"; break;
case bg::is_collinear_connect_opposite : s << "is_collinear_connect_opposite"; break;
// detailed connection results:
case bg::is_intersect_connect_s1p1 : s << "is_intersect_connect_s1p1"; break;
case bg::is_intersect_connect_s1p2 : s << "is_intersect_connect_s1p2"; break;
case bg::is_intersect_connect_s2p1 : s << "is_intersect_connect_s2p1"; break;
case bg::is_intersect_connect_s2p2 : s << "is_intersect_connect_s2p2"; break;
}
return s;
}
static std::string as_string(const bg::intersection_result& r)
{
std::stringstream out;
out << r;
return out.str();
}
typedef bg::model::point<double> P;
typedef bg::const_segment<P> S;
static void test_intersection(double s1x1, double s1y1, double s1x2, double s1y2,
double s2x1, double s2y1, double s2x2, double s2y2,
// Expected results
bg::intersection_result expected_result,
int exptected_count, const P& exp_p1, const P& exp_p2)
{
S s1(P(s1x1, s1y1), P(s1x2, s1y2));
S s2(P(s2x1, s2y1), P(s2x2, s2y2));
std::vector<P> ip;
double ra, rb;
bg::intersection_result r = bg::intersection_s(s1, s2, ra, rb, ip);
r = bg::intersection_connect_result(r, ra, rb);
BOOST_CHECK_EQUAL(ip.size(), exptected_count);
BOOST_CHECK_EQUAL(as_string(expected_result), as_string(r));
if (ip.size() == 2 && ip[0] != exp_p1)
{
// Swap results, second point is not as expected, swap results, order is not prescribed,
// it might be OK.
std::reverse(ip.begin(), ip.end());
}
if (ip.size() >= 1)
{
BOOST_CHECK_EQUAL(ip[0], exp_p1);
}
if (ip.size() >= 2)
{
BOOST_CHECK_EQUAL(ip[1], exp_p2);
}
/*
std::cout << exptected_count << " " << r;
if (exptected_count >= 1) std::cout << " " << ip[0];
if (exptected_count >= 2) std::cout << " " << ip[1];
std::cout << std::endl;
*/
}
//BOOST_AUTO_TEST_CASE( test1 )
int test_main( int , char* [] )
{
// Identical cases
test_intersection(0,0, 1,1, 0,0, 1,1, bg::is_collinear_overlap, 2, P(0,0), P(1,1));
test_intersection(1,1, 0,0, 0,0, 1,1, bg::is_collinear_overlap_opposite, 2, P(1,1), P(0,0));
test_intersection(0,1, 0,2, 0,1, 0,2, bg::is_collinear_overlap, 2, P(0,1), P(0,2)); // Vertical
test_intersection(0,2, 0,1, 0,1, 0,2, bg::is_collinear_overlap_opposite, 2, P(0,2), P(0,1)); // Vertical
// Overlap cases
test_intersection(0,0, 1,1, -0.5,-0.5, 2,2, bg::is_collinear_overlap, 2, P(0,0), P(1,1));
test_intersection(0,0, 1,1, 0.5,0.5, 1.5,1.5, bg::is_collinear_overlap, 2, P(0.5,0.5), P(1,1));
test_intersection(0,0, 0,1, 0,-10, 0,10, bg::is_collinear_overlap, 2, P(0,0), P(0,1)); // Vertical
test_intersection(0,0, 0,1, 0,10, 0,-10, bg::is_collinear_overlap_opposite, 2, P(0,0), P(0,1)); // Vertical
test_intersection(0,0, 1,1, 1,1, 2,2, bg::is_collinear_connect, 1, P(1,1), P(0,0)); // Single point
// Colinear, non overlap cases
test_intersection(0,0, 1,1, 1.5,1.5, 2.5,2.5, bg::is_collinear_no, 0, P(0,0), P(0,0));
test_intersection(0,0, 0,1, 0,5, 0,6, bg::is_collinear_no, 0, P(0,0), P(0,0)); // Vertical
// Parallel cases
test_intersection(0,0, 1,1, 1,0, 2,1, bg::is_parallel, 0, P(0,0), P(0,1));
// Intersect cases
test_intersection(0,2, 4,2, 3,0, 3,4, bg::is_intersect, 1, P(3,2), P(0,0));
// Non intersect cases
// Single point cases
test_intersection(0,0, 0,0, 1,1, 2,2, bg::is_collinear_no, 0, P(1,1), P(0,0)); // Colinear/no
test_intersection(2,2, 2,2, 1,1, 3,3, bg::is_collinear_one, 1, P(2,2.01), P(0,0)); // On segment
test_intersection(1,1, 3,3, 2,2, 2,2, bg::is_collinear_one, 1, P(2,2), P(0,0)); // On segment
test_intersection(1,1, 3,3, 1,1, 1,1, bg::is_collinear_one, 1, P(1,1), P(0,0)); // On segment, start
test_intersection(1,1, 3,3, 3,3, 3,3, bg::is_collinear_one, 1, P(3,3), P(0,0)); // On segment, end
return 0;
}
|