1 // Boost.Geometry (aka GGL, Generic Geometry Library)
4 // Copyright (c) 2009-2012 Barend Gehrels, Amsterdam, the Netherlands.
6 // Use, modification and distribution is subject to the Boost Software License,
7 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
10 #define BOOST_GEOMETRY_INCLUDE_SELF_TURNS
12 #define BOOST_GEOMETRY_REPORT_OVERLAY_ERROR
13 #define BOOST_GEOMETRY_NO_BOOST_TEST
15 #include <test_overlay_p_q.hpp>
17 #include <boost/program_options.hpp>
18 #include <boost/random/linear_congruential.hpp>
19 #include <boost/random/uniform_int.hpp>
20 #include <boost/random/uniform_real.hpp>
21 #include <boost/random/variate_generator.hpp>
22 #include <boost/timer.hpp>
25 template <typename Polygon
, typename Generator
>
26 inline void make_polygon(Polygon
& polygon
, Generator
& generator
, bool triangular
)
28 typedef typename
bg::point_type
<Polygon
>::type point_type
;
29 typedef typename
bg::coordinate_type
<Polygon
>::type coordinate_type
;
35 typename
bg::ring_type
<Polygon
>::type
& ring
= bg::exterior_ring(polygon
);
38 bg::set
<0>(p
, x
); bg::set
<1>(p
, y
); ring
.push_back(p
);
39 bg::set
<0>(p
, x
); bg::set
<1>(p
, y
+ 1); ring
.push_back(p
);
40 bg::set
<0>(p
, x
+ 1); bg::set
<1>(p
, y
+ 1); ring
.push_back(p
);
41 bg::set
<0>(p
, x
+ 1); bg::set
<1>(p
, y
); ring
.push_back(p
);
42 bg::set
<0>(p
, x
); bg::set
<1>(p
, y
); ring
.push_back(p
);
46 // Remove a point depending on generator
47 int c
= generator() % 4;
50 ring
.erase(ring
.begin() + c
);
57 template <typename MultiPolygon
, typename Generator
>
58 bool test_recursive_boxes(MultiPolygon
& result
, int& index
,
60 int level
, bool triangular
, p_q_settings
const& settings
)
69 make_polygon(p
.front(), generator
, triangular
);
70 make_polygon(q
.front(), generator
, triangular
);
78 if (! test_recursive_boxes(p
, index
, generator
, level
- 1, triangular
, settings
)
79 || ! test_recursive_boxes(q
, index
, generator
, level
- 1, triangular
, settings
))
85 typedef typename
boost::range_value
<MultiPolygon
>::type polygon
;
87 std::ostringstream out
;
88 out
<< "recursive_box_" << index
++ << "_" << level
;
90 if (! test_overlay_p_q
93 typename
bg::coordinate_type
<MultiPolygon
>::type
94 >(out
.str(), p
, q
, settings
))
100 bg::detail::union_::union_insert
103 >(p
, q
, std::back_inserter(mp
));
106 bg::simplify(mp
, result
, 0.01);
112 template <typename T
, bool Clockwise
, bool Closed
>
113 void test_all(int seed
, int count
, int field_size
, int level
, bool triangular
, p_q_settings
const& settings
)
117 typedef boost::minstd_rand base_generator_type
;
119 base_generator_type
generator(seed
);
121 boost::uniform_int
<> random_coordinate(0, field_size
- 1);
122 boost::variate_generator
<base_generator_type
&, boost::uniform_int
<> >
123 coordinate_generator(generator
, random_coordinate
);
125 typedef bg::model::polygon
127 bg::model::d2::point_xy
<T
>, Clockwise
, Closed
129 typedef bg::model::multi_polygon
<polygon
> mp
;
133 for(int i
= 0; i
< count
; i
++)
136 test_recursive_boxes
<mp
>(p
, index
, coordinate_generator
, level
, triangular
, settings
);
139 << "polygons: " << index
140 << " type: " << string_from_type
<T
>::name()
141 << " time: " << t
.elapsed() << std::endl
;
144 int main(int argc
, char** argv
)
148 namespace po
= boost::program_options
;
149 po::options_description
description("=== recursive_polygons ===\nAllowed options");
152 int seed
= static_cast<unsigned int>(std::time(0));
157 p_q_settings settings
;
158 std::string form
= "box";
160 description
.add_options()
161 ("help", "Help message")
162 ("seed", po::value
<int>(&seed
), "Initialization seed for random generator")
163 ("count", po::value
<int>(&count
)->default_value(1), "Number of tests")
164 ("diff", po::value
<bool>(&settings
.also_difference
)->default_value(false), "Include testing on difference")
165 ("validity", po::value
<bool>(&settings
.validity
)->default_value(true), "Include testing on validity")
166 ("level", po::value
<int>(&level
)->default_value(3), "Level to reach (higher->slower)")
167 ("size", po::value
<int>(&field_size
)->default_value(10), "Size of the field")
168 ("form", po::value
<std::string
>(&form
)->default_value("box"), "Form of the polygons (box, triangle)")
169 ("ccw", po::value
<bool>(&ccw
)->default_value(false), "Counter clockwise polygons")
170 ("open", po::value
<bool>(&open
)->default_value(false), "Open polygons")
171 ("wkt", po::value
<bool>(&settings
.wkt
)->default_value(false), "Create a WKT of the inputs, for all tests")
172 ("svg", po::value
<bool>(&settings
.svg
)->default_value(false), "Create a SVG for all tests")
175 po::variables_map varmap
;
176 po::store(po::parse_command_line(argc
, argv
, description
), varmap
);
179 if (varmap
.count("help")
180 || (form
!= "box" && form
!= "triangle"))
182 std::cout
<< description
<< std::endl
;
186 bool triangular
= form
!= "box";
191 test_all
<double, false, false>(seed
, count
, field_size
, level
, triangular
, settings
);
195 test_all
<double, false, true>(seed
, count
, field_size
, level
, triangular
, settings
);
199 test_all
<double, true, false>(seed
, count
, field_size
, level
, triangular
, settings
);
203 test_all
<double, true, true>(seed
, count
, field_size
, level
, triangular
, settings
);
206 #if defined(HAVE_TTMATH)
207 // test_all<ttmath_big, true, true>(seed, count, max, svg, level);
210 catch(std::exception
const& e
)
212 std::cout
<< "Exception " << e
.what() << std::endl
;
216 std::cout
<< "Other exception" << std::endl
;