]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/geometry/test/robustness/overlay/areal_areal/random_ellipses_stars.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / geometry / test / robustness / overlay / areal_areal / random_ellipses_stars.cpp
CommitLineData
7c673cae 1// Boost.Geometry (aka GGL, Generic Geometry Library)
20effc67 2// Robustness Test
7c673cae 3
1e59de90 4// Copyright (c) 2009-2021 Barend Gehrels, Amsterdam, the Netherlands.
7c673cae
FG
5
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)
9
7c673cae
FG
10#define BOOST_GEOMETRY_NO_BOOST_TEST
11
1e59de90
TL
12#ifndef BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE
13#define BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE
14#endif
15
7c673cae
FG
16#include <test_overlay_p_q.hpp>
17
18#include <boost/program_options.hpp>
7c673cae
FG
19#include <boost/random/linear_congruential.hpp>
20#include <boost/random/uniform_int.hpp>
21#include <boost/random/uniform_real.hpp>
22#include <boost/random/variate_generator.hpp>
23
24
25struct star_params
26{
27 int count; // points of ellipse, not of star
28 double factor_1;
29 double factor_2;
30 double center_x;
31 double center_y;
32 double rotation;
33 star_params(int c, double f1, double f2, double x, double y, double r = 0)
34 : count(c)
35 , factor_1(f1)
36 , factor_2(f2)
37 , center_x(x)
38 , center_y(y)
39 , rotation(r)
40 {}
41};
42
43
44
45template <typename Polygon>
46inline void make_star(Polygon& polygon, star_params const& p)
47{
48 typedef typename bg::point_type<Polygon>::type P;
49 typedef typename bg::select_most_precise
50 <
51 typename bg::coordinate_type<Polygon>::type,
52 long double
53 >::type coordinate_type;
54
55 // Create star
56 coordinate_type cx = 25.0;
57 coordinate_type cy = 25.0;
58
59 coordinate_type dx = 50.0;
60 coordinate_type dy = 50.0;
61
62 coordinate_type half = 0.5;
63 coordinate_type two = 2.0;
64
65 coordinate_type a1 = coordinate_type(p.factor_1) * half * dx;
66 coordinate_type b1 = coordinate_type(p.factor_1) * half * dy;
67 coordinate_type a2 = coordinate_type(p.factor_2) * half * dx;
68 coordinate_type b2 = coordinate_type(p.factor_2) * half * dy;
69
70 coordinate_type pi = boost::math::constants::pi<long double>();
71 coordinate_type delta = pi * two / coordinate_type(p.count - 1);
72 coordinate_type angle = coordinate_type(p.rotation) * delta;
73 for (int i = 0; i < p.count - 1; i++, angle += delta)
74 {
75 bool even = i % 2 == 0;
76 coordinate_type s = sin(angle);
77 coordinate_type c = cos(angle);
78 coordinate_type x = p.center_x + cx + (even ? a1 : a2) * s;
79 coordinate_type y = p.center_y + cy + (even ? b1 : b2) * c;
80 bg::exterior_ring(polygon).push_back(bg::make<P>(x, y));
81
82 }
83 bg::exterior_ring(polygon).push_back(bg::exterior_ring(polygon).front());
84 bg::correct(polygon);
85}
86
87
88template <typename T, bool Clockwise, bool Closed>
89void test_star_ellipse(int seed, int index, star_params const& par_p,
90 star_params const& par_q, p_q_settings const& settings)
91{
92 typedef bg::model::d2::point_xy<T> point_type;
93 typedef bg::model::polygon<point_type, Clockwise, Closed> polygon;
94
95 polygon p, q;
96 make_star(p, par_p);
97 make_star(q, par_q);
98
99 std::ostringstream out;
20effc67 100 out << "star_ellipse_" << seed << "_" << index;
7c673cae
FG
101 test_overlay_p_q<polygon, T>(out.str(), p, q, settings);
102}
103
104template <typename T, bool Clockwise, bool Closed>
105void test_type(int seed, int count, p_q_settings const& settings)
106{
20effc67 107 auto const t0 = std::chrono::high_resolution_clock::now();
7c673cae
FG
108 typedef boost::minstd_rand base_generator_type;
109
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);
113
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);
121
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);
129
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);
137
138 base_generator_type generator(seed);
139
140 boost::variate_generator<base_generator_type&, boost::uniform_real<> >
141 factor_generator(generator, random_factor);
142
143 boost::variate_generator<base_generator_type&, boost::uniform_real<> >
144 location_generator(generator, random_location);
145
146 boost::variate_generator<base_generator_type&, boost::uniform_real<> >
147 rotation_generator(generator, random_rotation);
148
149 boost::variate_generator<base_generator_type&, boost::uniform_int<> >
150 int_generator(generator, random_points);
151
152 for(int i = 0; i < count; i++)
153 {
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()),
161 settings);
162 }
20effc67
TL
163 auto const t = std::chrono::high_resolution_clock::now();
164 auto const elapsed_ms = std::chrono::duration_cast<std::chrono::milliseconds>(t - t0).count();
7c673cae
FG
165 std::cout
166 << "type: " << string_from_type<T>::name()
20effc67 167 << " time: " << elapsed_ms / 1000.0 << std::endl;
7c673cae
FG
168}
169
170template <bool Clockwise, bool Closed>
171void test_all(std::string const& type, int seed, int count, p_q_settings settings)
172{
1e59de90 173#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
7c673cae
FG
174 if (type == "float")
175 {
176 test_type<float, Clockwise, Closed>(seed, count, settings);
177 }
178 else if (type == "double")
1e59de90 179#endif
7c673cae
FG
180 {
181 test_type<double, Clockwise, Closed>(seed, count, settings);
182 }
7c673cae
FG
183}
184
185
186int main(int argc, char** argv)
187{
20effc67 188 BoostGeometryWriteTestConfiguration();
7c673cae
FG
189 try
190 {
191 namespace po = boost::program_options;
192 po::options_description description("=== random_ellipses_stars ===\nAllowed options");
193
194 int count = 1;
195 int seed = static_cast<unsigned int>(std::time(0));
1e59de90 196 std::string type = "double";
7c673cae
FG
197 bool ccw = false;
198 bool open = false;
199 p_q_settings settings;
200
201 description.add_options()
202 ("help", "Help message")
203 ("seed", po::value<int>(&seed), "Initialization seed for random generator")
204 ("count", po::value<int>(&count)->default_value(1), "Number of tests")
205 ("diff", po::value<bool>(&settings.also_difference)->default_value(false), "Include testing on difference")
1e59de90 206#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
7c673cae
FG
207 ("ccw", po::value<bool>(&ccw)->default_value(false), "Counter clockwise polygons")
208 ("open", po::value<bool>(&open)->default_value(false), "Open polygons")
1e59de90
TL
209 ("type", po::value<std::string>(&type)->default_value("double"), "Type (float,double)")
210#endif
7c673cae
FG
211 ("wkt", po::value<bool>(&settings.wkt)->default_value(false), "Create a WKT of the inputs, for all tests")
212 ("svg", po::value<bool>(&settings.svg)->default_value(false), "Create a SVG for all tests")
213 ;
214
215 po::variables_map varmap;
216 po::store(po::parse_command_line(argc, argv, description), varmap);
217 po::notify(varmap);
218
219 if (varmap.count("help"))
220 {
221 std::cout << description << std::endl;
222 return 1;
223 }
224
1e59de90 225#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
7c673cae
FG
226 if (ccw && open)
227 {
228 test_all<false, false>(type, seed, count, settings);
229 }
230 else if (ccw)
231 {
232 test_all<false, true>(type, seed, count, settings);
233 }
234 else if (open)
235 {
236 test_all<true, false>(type, seed, count, settings);
237 }
238 else
1e59de90 239#endif
7c673cae
FG
240 {
241 test_all<true, true>(type, seed, count, settings);
242 }
243 }
244 catch(std::exception const& e)
245 {
246 std::cout << "Exception " << e.what() << std::endl;
247 }
248 catch(...)
249 {
250 std::cout << "Other exception" << std::endl;
251 }
252
253 return 0;
254}