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_REPORT_OVERLAY_ERROR
11 #define BOOST_GEOMETRY_NO_BOOST_TEST
16 #include <boost/program_options.hpp>
17 #include <boost/random/linear_congruential.hpp>
18 #include <boost/random/uniform_int.hpp>
19 #include <boost/random/uniform_real.hpp>
20 #include <boost/random/variate_generator.hpp>
21 #include <boost/timer.hpp>
23 #include <boost/geometry.hpp>
24 #include <boost/geometry/geometries/geometries.hpp>
25 #include <boost/geometry/geometries/point_xy.hpp>
26 #include <boost/geometry/io/svg/svg_mapper.hpp>
39 namespace bg
= boost::geometry
;
41 template <typename Geometry1
, typename Geometry2
>
42 void create_svg(std::string
const& filename
, Geometry1
const& points
, Geometry2
const& hull
)
44 typedef typename
boost::geometry::point_type
<Geometry1
>::type point_type
;
46 boost::geometry::model::box
<point_type
> box
;
47 bg::envelope(hull
, box
);
48 bg::buffer(box
, box
, 1.0);
50 std::ofstream
svg(filename
.c_str());
51 boost::geometry::svg_mapper
<point_type
> mapper(svg
, 800, 800);
54 mapper
.map(hull
, "opacity:0.8;fill:none;stroke:rgb(255,0,255);stroke-width:4;stroke-dasharray:1,7;stroke-linecap:round");
55 mapper
.map(points
, "fill-opacity:0.5;fill:rgb(0,0,255);", 5);
59 template <typename MultiPoint
, typename Generator
>
60 inline void make_multi_point(MultiPoint
& mp
, Generator
& generator
, int pcount
)
62 typedef typename
bg::point_type
<MultiPoint
>::type point_type
;
63 typedef typename
bg::coordinate_type
<MultiPoint
>::type coordinate_type
;
65 for(int i
= 0; i
< pcount
; i
++)
79 template <typename MultiPoint
, typename Polygon
>
80 bool check_hull(MultiPoint
const& mp
, Polygon
const& poly
)
82 for(typename
boost::range_iterator
<MultiPoint
const>::type it
= boost::begin(mp
);
86 if (! bg::covered_by(*it
, poly
))
95 template <typename MultiPoint
, typename Generator
>
96 void test_random_multi_points(MultiPoint
& result
, int& index
,
98 int pcount
, settings_type
const& settings
)
100 typedef typename
bg::point_type
<MultiPoint
>::type point_type
;
103 bg::model::polygon
<point_type
> hull
;
105 make_multi_point(mp
, generator
, pcount
);
106 bg::convex_hull(mp
, hull
);
107 // Check if each point lies in the hull
108 bool correct
= check_hull(mp
, hull
);
111 std::cout
<< "ERROR! " << std::endl
112 << bg::wkt(mp
) << std::endl
113 << bg::wkt(hull
) << std::endl
118 if (settings
.svg
|| ! correct
)
120 std::ostringstream out
;
121 out
<< "random_mp_" << index
++ << "_" << pcount
<< ".svg";
122 create_svg(out
.str(), mp
, hull
);
127 << "input: " << bg::wkt(mp
) << std::endl
128 << "output: " << bg::wkt(hull
) << std::endl
135 template <typename T
>
136 void test_all(int seed
, int count
, int field_size
, int pcount
, settings_type
const& settings
)
140 typedef boost::minstd_rand base_generator_type
;
142 base_generator_type
generator(seed
);
144 boost::uniform_int
<> random_coordinate(0, field_size
- 1);
145 boost::variate_generator
<base_generator_type
&, boost::uniform_int
<> >
146 coordinate_generator(generator
, random_coordinate
);
148 typedef bg::model::multi_point
150 bg::model::d2::point_xy
<T
>
154 for(int i
= 0; i
< count
; i
++)
157 test_random_multi_points
<mp
>(p
, index
, coordinate_generator
, pcount
, settings
);
160 << "points: " << index
161 << " type: " << typeid(T
).name()
162 << " time: " << t
.elapsed() << std::endl
;
165 int main(int argc
, char** argv
)
169 namespace po
= boost::program_options
;
170 po::options_description
description("=== random_multi_points ===\nAllowed options");
172 std::string type
= "double";
174 int seed
= static_cast<unsigned int>(std::time(0));
177 settings_type settings
;
179 description
.add_options()
180 ("help", "Help message")
181 ("seed", po::value
<int>(&seed
), "Initialization seed for random generator")
182 ("count", po::value
<int>(&count
)->default_value(1), "Number of tests")
183 ("number", po::value
<int>(&pcount
)->default_value(30), "Number of points")
184 ("size", po::value
<int>(&field_size
)->default_value(10), "Size of the field")
185 ("type", po::value
<std::string
>(&type
)->default_value("double"), "Type (int,float,double)")
186 ("wkt", po::value
<bool>(&settings
.wkt
)->default_value(false), "Create a WKT of the inputs, for all tests")
187 ("svg", po::value
<bool>(&settings
.svg
)->default_value(false), "Create a SVG for all tests")
190 po::variables_map varmap
;
191 po::store(po::parse_command_line(argc
, argv
, description
), varmap
);
194 if (varmap
.count("help"))
196 std::cout
<< description
<< std::endl
;
202 test_all
<float>(seed
, count
, field_size
, pcount
, settings
);
204 else if (type
== "double")
206 test_all
<double>(seed
, count
, field_size
, pcount
, settings
);
208 else if (type
== "int")
210 test_all
<int>(seed
, count
, field_size
, pcount
, settings
);
214 catch(std::exception
const& e
)
216 std::cout
<< "Exception " << e
.what() << std::endl
;
220 std::cout
<< "Other exception" << std::endl
;