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_REPORT_OVERLAY_ERROR
11 #define BOOST_GEOMETRY_NO_BOOST_TEST
14 #include <test_overlay_p_q.hpp>
16 #include <boost/program_options.hpp>
17 #include <boost/timer.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>
26 int count
; // points of ellipse, not of star
32 star_params(int c
, double f1
, double f2
, double x
, double y
, double r
= 0)
44 template <typename Polygon
>
45 inline void make_star(Polygon
& polygon
, star_params
const& p
)
47 typedef typename
bg::point_type
<Polygon
>::type P
;
48 typedef typename
bg::select_most_precise
50 typename
bg::coordinate_type
<Polygon
>::type
,
52 >::type coordinate_type
;
55 coordinate_type cx
= 25.0;
56 coordinate_type cy
= 25.0;
58 coordinate_type dx
= 50.0;
59 coordinate_type dy
= 50.0;
61 coordinate_type half
= 0.5;
62 coordinate_type two
= 2.0;
64 coordinate_type a1
= coordinate_type(p
.factor_1
) * half
* dx
;
65 coordinate_type b1
= coordinate_type(p
.factor_1
) * half
* dy
;
66 coordinate_type a2
= coordinate_type(p
.factor_2
) * half
* dx
;
67 coordinate_type b2
= coordinate_type(p
.factor_2
) * half
* dy
;
69 coordinate_type pi
= boost::math::constants::pi
<long double>();
70 coordinate_type delta
= pi
* two
/ coordinate_type(p
.count
- 1);
71 coordinate_type angle
= coordinate_type(p
.rotation
) * delta
;
72 for (int i
= 0; i
< p
.count
- 1; i
++, angle
+= delta
)
74 bool even
= i
% 2 == 0;
75 coordinate_type s
= sin(angle
);
76 coordinate_type c
= cos(angle
);
77 coordinate_type x
= p
.center_x
+ cx
+ (even
? a1
: a2
) * s
;
78 coordinate_type y
= p
.center_y
+ cy
+ (even
? b1
: b2
) * c
;
79 bg::exterior_ring(polygon
).push_back(bg::make
<P
>(x
, y
));
82 bg::exterior_ring(polygon
).push_back(bg::exterior_ring(polygon
).front());
87 template <typename T
, bool Clockwise
, bool Closed
>
88 void test_star_ellipse(int seed
, int index
, star_params
const& par_p
,
89 star_params
const& par_q
, p_q_settings
const& settings
)
91 typedef bg::model::d2::point_xy
<T
> point_type
;
92 typedef bg::model::polygon
<point_type
, Clockwise
, Closed
> polygon
;
98 std::ostringstream out
;
99 out
<< "rse_" << seed
<< "_" << index
;
100 test_overlay_p_q
<polygon
, T
>(out
.str(), p
, q
, settings
);
103 template <typename T
, bool Clockwise
, bool Closed
>
104 void test_type(int seed
, int count
, p_q_settings
const& settings
)
108 typedef boost::minstd_rand base_generator_type
;
110 //boost::uniform_real<> random_factor(0.5, 1.2);
111 //boost::uniform_real<> random_location(-10.0, 10.0);
112 //boost::uniform_int<> random_points(5, 20);
114 // This set (next 4 lines) are now solved for the most part
115 // 2009-12-03, 3 or 4 errors in 1000000 calls
116 // 2009-12-07, no errors in 1000000 calls
117 //boost::uniform_real<> random_factor(1.0 - 1e-3, 1.0 + 1e-3);
118 //boost::uniform_real<> random_location(-1e-3, 1e-3);
119 //boost::uniform_real<> random_rotation(-1e-3, 1e-3);
120 //boost::uniform_int<> random_points(3, 3);
122 // 2009-12-08, still errors, see notes
123 // 2009-12-09, (probably) solved by order on side
124 // 2010-01-16: solved (no errors in 1000000 calls)
125 //boost::uniform_real<> random_factor(1.0 - 1e-3, 1.0 + 1e-3);
126 //boost::uniform_real<> random_location(-1e-3, -1e-3);
127 //boost::uniform_real<> random_rotation(-1e-3, 1e-3);
128 //boost::uniform_int<> random_points(3, 4);
130 // This set (next 4 lines) are now solved ("distance-zero"/"merge iiii" problem)
131 // 2009-12-03: 5,50 -> 2:1 000 000 wrong (2009-12-03)
132 // 2010-01-16: solved (no errors in 10000000 calls)
133 boost::uniform_real
<> random_factor(0.3, 1.2);
134 boost::uniform_real
<> random_location(-20.0, +20.0); // -25.0, +25.0
135 boost::uniform_real
<> random_rotation(0, 0.5);
136 boost::uniform_int
<> random_points(5, 15);
138 base_generator_type
generator(seed
);
140 boost::variate_generator
<base_generator_type
&, boost::uniform_real
<> >
141 factor_generator(generator
, random_factor
);
143 boost::variate_generator
<base_generator_type
&, boost::uniform_real
<> >
144 location_generator(generator
, random_location
);
146 boost::variate_generator
<base_generator_type
&, boost::uniform_real
<> >
147 rotation_generator(generator
, random_rotation
);
149 boost::variate_generator
<base_generator_type
&, boost::uniform_int
<> >
150 int_generator(generator
, random_points
);
152 for(int i
= 0; i
< count
; i
++)
154 test_star_ellipse
<T
, Clockwise
, Closed
>(seed
, i
+ 1,
155 star_params(int_generator() * 2 + 1,
156 factor_generator(), factor_generator(),
157 location_generator(), location_generator(), rotation_generator()),
158 star_params(int_generator() * 2 + 1,
159 factor_generator(), factor_generator(),
160 location_generator(), location_generator(), rotation_generator()),
164 << "type: " << string_from_type
<T
>::name()
165 << " time: " << t
.elapsed() << std::endl
;
168 template <bool Clockwise
, bool Closed
>
169 void test_all(std::string
const& type
, int seed
, int count
, p_q_settings settings
)
173 test_type
<float, Clockwise
, Closed
>(seed
, count
, settings
);
175 else if (type
== "double")
177 test_type
<double, Clockwise
, Closed
>(seed
, count
, settings
);
179 #if defined(HAVE_TTMATH)
180 else if (type
== "ttmath")
182 test_type
<ttmath_big
, Clockwise
, Closed
>(seed
, count
, settings
);
188 int main(int argc
, char** argv
)
192 namespace po
= boost::program_options
;
193 po::options_description
description("=== random_ellipses_stars ===\nAllowed options");
196 int seed
= static_cast<unsigned int>(std::time(0));
197 std::string type
= "float";
200 p_q_settings settings
;
202 description
.add_options()
203 ("help", "Help message")
204 ("seed", po::value
<int>(&seed
), "Initialization seed for random generator")
205 ("count", po::value
<int>(&count
)->default_value(1), "Number of tests")
206 ("diff", po::value
<bool>(&settings
.also_difference
)->default_value(false), "Include testing on difference")
207 ("ccw", po::value
<bool>(&ccw
)->default_value(false), "Counter clockwise polygons")
208 ("open", po::value
<bool>(&open
)->default_value(false), "Open polygons")
209 ("type", po::value
<std::string
>(&type
)->default_value("float"), "Type (float,double)")
210 ("wkt", po::value
<bool>(&settings
.wkt
)->default_value(false), "Create a WKT of the inputs, for all tests")
211 ("svg", po::value
<bool>(&settings
.svg
)->default_value(false), "Create a SVG for all tests")
214 po::variables_map varmap
;
215 po::store(po::parse_command_line(argc
, argv
, description
), varmap
);
218 if (varmap
.count("help"))
220 std::cout
<< description
<< std::endl
;
226 test_all
<false, false>(type
, seed
, count
, settings
);
230 test_all
<false, true>(type
, seed
, count
, settings
);
234 test_all
<true, false>(type
, seed
, count
, settings
);
238 test_all
<true, true>(type
, seed
, count
, settings
);
241 catch(std::exception
const& e
)
243 std::cout
<< "Exception " << e
.what() << std::endl
;
247 std::cout
<< "Other exception" << std::endl
;