1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 // Robustness Test - convex_hull
4 // Copyright (c) 2012-2015 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_NO_BOOST_TEST
15 #include <boost/program_options.hpp>
16 #include <boost/random/linear_congruential.hpp>
17 #include <boost/random/uniform_int.hpp>
18 #include <boost/random/uniform_real.hpp>
19 #include <boost/random/variate_generator.hpp>
20 #include <boost/timer.hpp>
22 #include <boost/geometry.hpp>
23 #include <boost/geometry/geometries/geometries.hpp>
24 #include <boost/geometry/geometries/point_xy.hpp>
25 #include <boost/geometry/io/svg/svg_mapper.hpp>
38 namespace bg
= boost::geometry
;
40 template <typename Geometry1
, typename Geometry2
>
41 void create_svg(std::string
const& filename
, Geometry1
const& points
, Geometry2
const& hull
)
43 typedef typename
boost::geometry::point_type
<Geometry1
>::type point_type
;
45 boost::geometry::model::box
<point_type
> box
;
46 bg::envelope(hull
, box
);
47 bg::buffer(box
, box
, 1.0);
49 std::ofstream
svg(filename
.c_str());
50 boost::geometry::svg_mapper
<point_type
> mapper(svg
, 800, 800);
53 mapper
.map(hull
, "opacity:0.8;fill:none;stroke:rgb(255,0,255);stroke-width:4;stroke-dasharray:1,7;stroke-linecap:round");
54 mapper
.map(points
, "fill-opacity:0.5;fill:rgb(0,0,255);", 5);
58 template <typename MultiPoint
, typename Generator
>
59 inline void make_multi_point(MultiPoint
& mp
, Generator
& generator
, int pcount
)
61 typedef typename
bg::point_type
<MultiPoint
>::type point_type
;
62 typedef typename
bg::coordinate_type
<MultiPoint
>::type coordinate_type
;
64 for(int i
= 0; i
< pcount
; i
++)
78 template <typename MultiPoint
, typename Polygon
>
79 bool check_hull(MultiPoint
const& mp
, Polygon
const& poly
)
81 for(typename
boost::range_iterator
<MultiPoint
const>::type it
= boost::begin(mp
);
85 if (! bg::covered_by(*it
, poly
))
94 template <typename MultiPoint
, typename Generator
>
95 void test_random_multi_points(MultiPoint
& result
, int& index
,
97 int pcount
, settings_type
const& settings
)
99 typedef typename
bg::point_type
<MultiPoint
>::type point_type
;
102 bg::model::polygon
<point_type
> hull
;
104 make_multi_point(mp
, generator
, pcount
);
105 bg::convex_hull(mp
, hull
);
106 // Check if each point lies in the hull
107 bool correct
= check_hull(mp
, hull
);
110 std::cout
<< "ERROR! " << std::endl
111 << bg::wkt(mp
) << std::endl
112 << bg::wkt(hull
) << std::endl
117 if (settings
.svg
|| ! correct
)
119 std::ostringstream out
;
120 out
<< "random_mp_" << index
++ << "_" << pcount
<< ".svg";
121 create_svg(out
.str(), mp
, hull
);
126 << "input: " << bg::wkt(mp
) << std::endl
127 << "output: " << bg::wkt(hull
) << std::endl
134 template <typename T
>
135 void test_all(int seed
, int count
, int field_size
, int pcount
, settings_type
const& settings
)
139 typedef boost::minstd_rand base_generator_type
;
141 base_generator_type
generator(seed
);
143 boost::uniform_int
<> random_coordinate(0, field_size
- 1);
144 boost::variate_generator
<base_generator_type
&, boost::uniform_int
<> >
145 coordinate_generator(generator
, random_coordinate
);
147 typedef bg::model::multi_point
149 bg::model::d2::point_xy
<T
>
153 for(int i
= 0; i
< count
; i
++)
156 test_random_multi_points
<mp
>(p
, index
, coordinate_generator
, pcount
, settings
);
159 << "points: " << index
160 << " type: " << typeid(T
).name()
161 << " time: " << t
.elapsed() << std::endl
;
164 int main(int argc
, char** argv
)
168 namespace po
= boost::program_options
;
169 po::options_description
description("=== random_multi_points ===\nAllowed options");
171 std::string type
= "double";
173 int seed
= static_cast<unsigned int>(std::time(0));
176 settings_type settings
;
178 description
.add_options()
179 ("help", "Help message")
180 ("seed", po::value
<int>(&seed
), "Initialization seed for random generator")
181 ("count", po::value
<int>(&count
)->default_value(1), "Number of tests")
182 ("number", po::value
<int>(&pcount
)->default_value(30), "Number of points")
183 ("size", po::value
<int>(&field_size
)->default_value(10), "Size of the field")
184 ("type", po::value
<std::string
>(&type
)->default_value("double"), "Type (int,float,double)")
185 ("wkt", po::value
<bool>(&settings
.wkt
)->default_value(false), "Create a WKT of the inputs, for all tests")
186 ("svg", po::value
<bool>(&settings
.svg
)->default_value(false), "Create a SVG for all tests")
189 po::variables_map varmap
;
190 po::store(po::parse_command_line(argc
, argv
, description
), varmap
);
193 if (varmap
.count("help"))
195 std::cout
<< description
<< std::endl
;
201 test_all
<float>(seed
, count
, field_size
, pcount
, settings
);
203 else if (type
== "double")
205 test_all
<double>(seed
, count
, field_size
, pcount
, settings
);
207 else if (type
== "int")
209 test_all
<int>(seed
, count
, field_size
, pcount
, settings
);
213 catch(std::exception
const& e
)
215 std::cout
<< "Exception " << e
.what() << std::endl
;
219 std::cout
<< "Other exception" << std::endl
;