PageRenderTime 39ms CodeModel.GetById 6ms app.highlight 29ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/libs/geometry/test/strategies/segment_intersection.cpp

http://hadesmem.googlecode.com/
C++ | 374 lines | 241 code | 57 blank | 76 comment | 27 complexity | 87450bb4773244b906fd3f880e9521b1 MD5 | raw file
  1// Boost.Geometry (aka GGL, Generic Geometry Library)
  2// Unit Test
  3
  4// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
  5// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
  6// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
  7
  8// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  9// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
 10
 11// Use, modification and distribution is subject to the Boost Software License,
 12// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 13// http://www.boost.org/LICENSE_1_0.txt)
 14
 15
 16#if defined(_MSC_VER)
 17// We deliberately mix float/double's here so turn off warning
 18#pragma warning( disable : 4244 )
 19#endif // defined(_MSC_VER)
 20
 21#define HAVE_MATRIX_AS_STRING
 22
 23
 24#include <geometry_test_common.hpp>
 25
 26#include <boost/geometry/algorithms/assign.hpp>
 27
 28#include <boost/geometry/strategies/cartesian/cart_intersect.hpp>
 29#include <boost/geometry/strategies/intersection_result.hpp>
 30
 31#include <boost/geometry/policies/relate/intersection_points.hpp>
 32#include <boost/geometry/policies/relate/direction.hpp>
 33//#include <boost/geometry/policies/relate/de9im.hpp>
 34#include <boost/geometry/policies/relate/tupled.hpp>
 35
 36#include <boost/geometry/algorithms/intersection.hpp>
 37
 38
 39#include <boost/geometry/geometries/point.hpp>
 40#include <boost/geometry/geometries/segment.hpp>
 41#include <boost/geometry/geometries/adapted/boost_tuple.hpp>
 42
 43BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian);
 44
 45
 46template <typename R>
 47void print_is(R const& is)
 48{
 49#ifdef REPORT
 50    for (int i = 0; i < is.count; i++)
 51    {
 52        std::cout
 53            << " (" << bg::get<0>(is.intersections[i])
 54            << "," << bg::get<1>(is.intersections[i])
 55            << ")";
 56    }
 57#endif
 58}
 59/*
 60void print_im(bg::de9im const& im)
 61{
 62#ifdef REPORT
 63    if (im.equals()) std::cout << " EQUALS";
 64    if (im.disjoint()) std::cout << " DISJOINT";
 65    if (im.intersects()) std::cout << " INTERSECTS";
 66    if (im.touches()) std::cout << " TOUCHES";
 67    if (im.crosses()) std::cout << " CROSSES";
 68    if (im.overlaps()) std::cout << " OVERLAPS";
 69    if (im.within()) std::cout << " WITHIN";
 70    if (im.contains()) std::cout << " CONTAINS";
 71
 72    //std::cout << " ra=" << im.ra << " rb=" << im.rb;
 73#endif
 74}
 75*/
 76
 77template <typename P>
 78static void test_segment_intersection(int caseno,
 79                int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4,
 80                std::string const& expected_matrix,
 81                std::string const& expected_characteristic,
 82                std::string const& expected_direction_a = "",
 83                std::string const& expected_direction_b = "",
 84                int expected_x1 = -99, int expected_y1 = -99,
 85                int expected_x2 = -99, int expected_y2 = -99)
 86{
 87    using namespace boost::geometry;
 88
 89#ifdef REPORT
 90    std::cout << "CASE " << caseno << std::endl;
 91#endif
 92
 93    typedef typename bg::coordinate_type<P>::type coordinate_type;
 94    typedef bg::model::referring_segment<const P> segment_type;
 95
 96    P p1, p2, p3, p4;
 97    bg::assign_values(p1, x1, y1);
 98    bg::assign_values(p2, x2, y2);
 99    bg::assign_values(p3, x3, y3);
100    bg::assign_values(p4, x4, y4);
101
102    segment_type s12(p1,p2);
103    segment_type s34(p3,p4);
104
105    // Get the intersection point (or two points)
106    segment_intersection_points<P> is
107        = strategy::intersection::relate_cartesian_segments
108        <
109            policies::relate::segments_intersection_points
110                <
111                    segment_type,
112                    segment_type,
113                    segment_intersection_points<P>
114                >
115        >::apply(s12, s34);
116
117    // Get the Dimension Extended 9 Intersection Matrix (de9im) for Segments
118    // (this one is extended by GGL having opposite)
119    /***
120    TODO TO BE UPDATED (if necessary) OR DELETED
121    de9im_segment matrix = strategy::intersection::relate_cartesian_segments
122        <
123            policies::relate::segments_de9im<segment_type, segment_type>
124        >::apply(s12, s34);
125    ***/
126
127    // Get just a character for Left/Right/intersects/etc, purpose is more for debugging
128    policies::relate::direction_type dir = strategy::intersection::relate_cartesian_segments
129        <
130            policies::relate::segments_direction<segment_type, segment_type>
131        >::apply(s12, s34);
132
133    int expected_count = 0;
134
135    if (expected_x1 != -99 && expected_y1 != -99)
136    {
137        expected_count++;
138
139        BOOST_CHECK(is.count >= 1);
140        BOOST_CHECK_CLOSE(bg::get<0>(is.intersections[0]),
141                coordinate_type(expected_x1), 0.001);
142        BOOST_CHECK_CLOSE(bg::get<1>(is.intersections[0]),
143                coordinate_type(expected_y1), 0.001);
144    }
145    if (expected_x2 != -99 && expected_y2 != -99)
146    {
147        expected_count++;
148
149        BOOST_CHECK(is.count >= 2);
150        BOOST_CHECK_CLOSE(bg::get<0>(is.intersections[1]),
151                coordinate_type(expected_x2), 0.001);
152        BOOST_CHECK_CLOSE(bg::get<1>(is.intersections[1]),
153                coordinate_type(expected_y2), 0.001);
154    }
155    BOOST_CHECK_EQUAL(is.count, expected_count);
156
157    //BOOST_CHECK_EQUAL(expected_matrix, matrix.matrix_as_string());
158
159    std::string characteristic;
160    characteristic += dir.how;
161
162    BOOST_CHECK_EQUAL(characteristic, expected_characteristic);
163
164    if (!expected_direction_a.empty())
165    {
166        BOOST_CHECK_EQUAL(dir.dir_a == 1 ? "L"
167                    : dir.dir_a == -1 ? "R"
168                    : "-", expected_direction_a);
169    }
170    if (!expected_direction_b.empty())
171    {
172        BOOST_CHECK_EQUAL(dir.dir_b == 1 ? "L"
173                    : dir.dir_b == -1 ? "R"
174                    : "-", expected_direction_b);
175    }
176
177
178
179    // Things can also be used together
180    // -> intersection is only once calculated, two results
181    /***
182    typedef boost::tuple
183        <
184            de9im_segment,
185            policies::relate::direction_type
186        > tup;
187
188    tup t = strategy::intersection::relate_cartesian_segments
189        <
190            policies::relate::segments_tupled
191                <
192                    policies::relate::segments_de9im<segment_type, segment_type>,
193                    policies::relate::segments_direction<segment_type, segment_type>
194                >
195        >::apply(segment_type(p1,p2), segment_type(p3,p4));
196
197
198    //BOOST_CHECK_EQUAL(t.get<0>().matrix_as_string(), matrix.matrix_as_string());
199    BOOST_CHECK_EQUAL(t.get<1>().how, dir.how);
200    */
201
202#ifdef REPORT
203    //std::cout << std::endl << "\t" << matrix.as_string() << " ";
204    std::cout << "METHOD=" << c << " ";
205    print_is(is);
206    //print_im(matrix);
207    std::cout << std::endl;
208#endif
209
210    /*
211    To check with a spatial database: issue this statement
212    std::cout << "select relate("
213            << "GeomFromText(LINESTRING('" << x1 << " " << y1 << "," << x2 << " " << y2 << ")')"
214            << ", "
215            << "GeomFromText(LINESTRING('" << x3 << " " << y3 << "," << x4 << " " << y4 << ")')"
216            << ");"
217            << std::endl;
218    */
219
220
221    // Now use generic intersection.
222    std::vector<P> out;
223    bg::detail::intersection::intersection_insert<P>(s12, s34, std::back_inserter(out));
224
225    BOOST_CHECK_EQUAL(boost::size(out), expected_count);
226
227    if (expected_x1 != -99 && expected_y1 != -99
228        && is.count >= 1
229        && boost::size(out) >= 1)
230    {
231        BOOST_CHECK_CLOSE(bg::get<0>(out[0]),
232                coordinate_type(expected_x1), 0.001);
233        BOOST_CHECK_CLOSE(bg::get<1>(out[0]),
234                coordinate_type(expected_y1), 0.001);
235    }
236    if (expected_x2 != -99 && expected_y2 != -99
237        && is.count >= 2
238        && boost::size(out) >= 2)
239    {
240        BOOST_CHECK_CLOSE(bg::get<0>(out[1]),
241                coordinate_type(expected_x2), 0.001);
242        BOOST_CHECK_CLOSE(bg::get<1>(out[1]),
243                coordinate_type(expected_y2), 0.001);
244    }
245}
246
247
248template <typename P>
249void test_all()
250{
251    test_segment_intersection<P>( 1, 0,2, 2,0, 0,0, 2,2, "0-1--0102",
252        "i", "R", "L", 1, 1);
253    test_segment_intersection<P>( 2, 2,2, 3,1, 0,0, 2,2, "--1-00102",
254        "a", "R", "R", 2, 2);
255    test_segment_intersection<P>( 3, 3,1, 2,2, 0,0, 2,2, "--1-00102",
256        "t", "R", "L", 2, 2);
257    test_segment_intersection<P>( 4, 0,2, 1,1, 0,0, 2,2, "--10-0102",
258        "m", "L", "L", 1, 1);
259#ifdef REPORT
260    std::cout << std::endl;
261#endif
262
263    test_segment_intersection<P>( 5, 1,1, 0,2, 0,0, 2,2, "--10-0102",
264        "s", "L", "R", 1, 1);
265    test_segment_intersection<P>( 6, 0,2, 2,0, 0,0, 1,1, "-01--0102",
266        "m", "R", "R", 1, 1);
267    test_segment_intersection<P>( 7, 2,0, 0,2, 0,0, 1,1, "-01--0102",
268        "m", "L", "L", 1, 1);
269    test_segment_intersection<P>( 8, 2,3, 3,2, 0,0, 2,2, "--1--0102",
270        "d");
271#ifdef REPORT
272    std::cout << std::endl;
273#endif
274
275    test_segment_intersection<P>( 9, 0,0, 2,2, 0,0, 2,2, "1---0---2",
276        "e", "-", "-", 0, 0, 2, 2);
277    test_segment_intersection<P>(10, 2,2, 0,0, 0,0, 2,2, "1---0---2",
278        "e", "-", "-", 2, 2, 0, 0);
279    test_segment_intersection<P>(11, 1,1, 3,3, 0,0, 2,2, "1010-0102",
280        "c", "-", "-", 1, 1, 2, 2);
281    test_segment_intersection<P>(12, 3,3, 1,1, 0,0, 2,2, "1010-0102",
282        "c", "-", "-", 1, 1, 2, 2);
283#ifdef REPORT
284    std::cout << std::endl;
285#endif
286
287    test_segment_intersection<P>(13, 0,2, 2,2, 2,1, 2,3, "--10-0102",
288        "m", "L", "L", 2, 2);
289    test_segment_intersection<P>(14, 2,2, 2,4, 2,0, 2,2, "--1-00102",
290        "C", "-", "-", 2, 2);
291    test_segment_intersection<P>(15, 2,2, 2,4, 2,0, 2,1, "--1--0102",
292        "d");
293    test_segment_intersection<P>(16, 2,4, 2,2, 2,0, 2,1, "--1--0102",
294        "d");
295
296    test_segment_intersection<P>(17, 2,1, 2,3, 2,2, 2,4, "1010-0102",
297        "c", "-", "-", 2, 3, 2, 2);
298    test_segment_intersection<P>(18, 2,3, 2,1, 2,2, 2,4, "1010-0102",
299        "c", "-", "-", 2, 3, 2, 2);
300    test_segment_intersection<P>(19, 0,2, 2,2, 4,2, 2,2, "--1-00102",
301        "C", "-", "-", 2, 2);
302    test_segment_intersection<P>(20, 0,2, 2,2, 2,2, 4,2, "--1-00102",
303        "C", "-", "-", 2, 2);
304
305    test_segment_intersection<P>(21, 1,2, 3,2, 2,1, 2,3, "0-1--0102",
306        "i", "R", "L", 2, 2);
307    test_segment_intersection<P>(22, 2,4, 2,1, 2,1, 2,3, "101-00--2",
308        "c", "-", "-", 2, 1, 2, 3);
309    test_segment_intersection<P>(23, 2,4, 2,1, 2,3, 2,1, "101-00--2",
310        "c", "-", "-", 2, 3, 2, 1);
311    test_segment_intersection<P>(24, 1,1, 3,3, 0,0, 3,3, "1--00-102",
312        "c", "-", "-", 1, 1, 3, 3);
313
314    test_segment_intersection<P>(25, 2,0, 2,4, 2,1, 2,3, "101--0--2",
315        "c", "-", "-", 2, 1, 2, 3);
316    test_segment_intersection<P>(26, 2,0, 2,4, 2,3, 2,1, "101--0--2",
317        "c", "-", "-", 2, 3, 2, 1);
318    test_segment_intersection<P>(27, 0,0, 4,4, 1,1, 3,3, "101--0--2",
319        "c", "-", "-", 1, 1, 3, 3);
320    test_segment_intersection<P>(28, 0,0, 4,4, 3,3, 1,1, "101--0--2",
321        "c", "-", "-", 3, 3, 1, 1);
322
323    test_segment_intersection<P>(29, 1,1, 3,3, 0,0, 4,4, "1--0--102",
324        "c", "-", "-", 1, 1, 3, 3);
325    test_segment_intersection<P>(30, 0,0, 2,2, 2,2, 3,1, "--1-00102",
326        "a", "R", "R", 2, 2);
327    test_segment_intersection<P>(31, 0,0, 2,2, 2,2, 1,3, "--1-00102",
328        "a", "L", "L", 2, 2);
329    test_segment_intersection<P>(32, 0,0, 2,2, 1,1, 2,0, "-01--0102",
330        "s", "L", "R", 1, 1);
331
332    test_segment_intersection<P>(33, 0,0, 2,2, 1,1, 0,2, "-01--0102",
333        "s", "R", "L", 1, 1);
334    test_segment_intersection<P>(34, 2,2, 1,3, 0,0, 2,2, "--1-00102",
335        "a", "L", "L", 2, 2);
336    test_segment_intersection<P>(35, 2,2, 3,1, 0,0, 2,2, "--1-00102",
337        "a", "R", "R", 2, 2);
338    test_segment_intersection<P>(36, 0,0, 2,2, 0,2, 1,1, "-01--0102",
339        "m", "L", "L", 1, 1);
340
341    test_segment_intersection<P>(37, 0,0, 2,2, 2,0, 1,1, "-01--0102",
342        "m", "R", "R", 1, 1);
343    test_segment_intersection<P>(38, 1,1, 0,2, 0,0, 2,2, "--10-0102",
344        "s", "L", "R", 1, 1);
345    test_segment_intersection<P>(39, 1,1, 2,0, 0,0, 2,2, "--10-0102",
346        "s", "R", "L", 1, 1);
347    test_segment_intersection<P>(40, 2,0, 1,1, 0,0, 2,2, "--10-0102",
348        "m", "R", "R", 1, 1);
349
350    test_segment_intersection<P>(41, 1,2, 0,2, 2,2, 0,2, "1--00-102",
351        "c", "-", "-", 1, 2, 0, 2);
352    test_segment_intersection<P>(42, 2,1, 1,1, 2,2, 0,2, "--1--0102",
353        "p");
354    test_segment_intersection<P>(43, 4,1, 3,1, 2,2, 0,2, "--1--0102",
355        "p");
356    test_segment_intersection<P>(44, 4,2, 3,2, 2,2, 0,2, "--1--0102",
357        "d");
358
359    test_segment_intersection<P>(45, 2,0, 0,2, 0,0, 2,2, "0-1--0102",
360        "i", "L", "R", 1, 1);
361
362    // In figure: times 2
363    test_segment_intersection<P>(46, 8,2, 4,6, 0,0, 8, 8, "0-1--0102",
364        "i", "L", "R", 5, 5);
365}
366
367int test_main(int, char* [])
368{
369    std::cout << "Note this test is out-of-date and either obsolete or should be updated" << std::endl;
370    test_all<boost::tuple<double, double> >();
371    test_all<bg::model::point<float, 2, bg::cs::cartesian> >();
372    test_all<bg::model::point<double, 2, bg::cs::cartesian> >();
373    return 0;
374}