/Src/Dependencies/Boost/libs/geometry/test/algorithms/overlay/robustness/random_ellipses_stars.cpp

http://hadesmem.googlecode.com/ · C++ · 263 lines · 190 code · 46 blank · 27 comment · 18 complexity · a0b05a6ff5757062a41e4f63153eb4a3 MD5 · raw file

  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Unit Test
  3. // Copyright (c) 2009-2011 Barend Gehrels, Amsterdam, the Netherlands.
  4. // Use, modification and distribution is subject to the Boost Software License,
  5. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. #include <iostream>
  8. #include <sstream>
  9. #include <fstream>
  10. #include <iomanip>
  11. #include <string>
  12. #define BOOST_GEOMETRY_REPORT_OVERLAY_ERROR
  13. #define BOOST_GEOMETRY_NO_BOOST_TEST
  14. #include <boost/program_options.hpp>
  15. #include <boost/timer.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 <test_overlay_p_q.hpp>
  21. #include <boost/geometry/geometry.hpp>
  22. #include <boost/geometry/geometries/point_xy.hpp>
  23. struct star_params
  24. {
  25. int count; // points of ellipse, not of star
  26. double factor_1;
  27. double factor_2;
  28. double center_x;
  29. double center_y;
  30. double rotation;
  31. star_params(int c, double f1, double f2, double x, double y, double r = 0)
  32. : count(c)
  33. , factor_1(f1)
  34. , factor_2(f2)
  35. , center_x(x)
  36. , center_y(y)
  37. , rotation(r)
  38. {}
  39. };
  40. template <typename Polygon>
  41. inline void make_star(Polygon& polygon, star_params const& p)
  42. {
  43. typedef typename bg::point_type<Polygon>::type P;
  44. typedef typename bg::select_most_precise
  45. <
  46. typename bg::coordinate_type<Polygon>::type,
  47. long double
  48. >::type coordinate_type;
  49. // Create star
  50. coordinate_type cx = 25.0;
  51. coordinate_type cy = 25.0;
  52. coordinate_type dx = 50.0;
  53. coordinate_type dy = 50.0;
  54. coordinate_type half = 0.5;
  55. coordinate_type two = 2.0;
  56. coordinate_type a1 = coordinate_type(p.factor_1) * half * dx;
  57. coordinate_type b1 = coordinate_type(p.factor_1) * half * dy;
  58. coordinate_type a2 = coordinate_type(p.factor_2) * half * dx;
  59. coordinate_type b2 = coordinate_type(p.factor_2) * half * dy;
  60. coordinate_type pi = boost::math::constants::pi<long double>();
  61. coordinate_type delta = pi * two / coordinate_type(p.count - 1);
  62. coordinate_type angle = coordinate_type(p.rotation) * delta;
  63. for (int i = 0; i < p.count - 1; i++, angle += delta)
  64. {
  65. bool even = i % 2 == 0;
  66. coordinate_type s = sin(angle);
  67. coordinate_type c = cos(angle);
  68. coordinate_type x = p.center_x + cx + (even ? a1 : a2) * s;
  69. coordinate_type y = p.center_y + cy + (even ? b1 : b2) * c;
  70. bg::exterior_ring(polygon).push_back(bg::make<P>(x, y));
  71. }
  72. bg::exterior_ring(polygon).push_back(bg::exterior_ring(polygon).front());
  73. bg::correct(polygon);
  74. }
  75. template <typename T, bool Clockwise, bool Closed>
  76. void test_star_ellipse(int seed, int index, star_params const& par_p,
  77. star_params const& par_q, p_q_settings const& settings)
  78. {
  79. typedef bg::model::d2::point_xy<T> point_type;
  80. typedef bg::model::polygon<point_type, Clockwise, Closed> polygon;
  81. polygon p, q;
  82. make_star(p, par_p);
  83. make_star(q, par_q);
  84. std::ostringstream out;
  85. out << "rse_" << seed << "_" << index;
  86. test_overlay_p_q<polygon, T>(out.str(), p, q, settings);
  87. }
  88. template <typename T, bool Clockwise, bool Closed>
  89. void test_type(int seed, int count, p_q_settings const& settings)
  90. {
  91. boost::timer t;
  92. typedef boost::minstd_rand base_generator_type;
  93. //boost::uniform_real<> random_factor(0.5, 1.2);
  94. //boost::uniform_real<> random_location(-10.0, 10.0);
  95. //boost::uniform_int<> random_points(5, 20);
  96. // This set (next 4 lines) are now solved for the most part
  97. // 2009-12-03, 3 or 4 errors in 1000000 calls
  98. // 2009-12-07, no errors in 1000000 calls
  99. //boost::uniform_real<> random_factor(1.0 - 1e-3, 1.0 + 1e-3);
  100. //boost::uniform_real<> random_location(-1e-3, 1e-3);
  101. //boost::uniform_real<> random_rotation(-1e-3, 1e-3);
  102. //boost::uniform_int<> random_points(3, 3);
  103. // 2009-12-08, still errors, see notes
  104. // 2009-12-09, (probably) solved by order on side
  105. // 2010-01-16: solved (no errors in 1000000 calls)
  106. //boost::uniform_real<> random_factor(1.0 - 1e-3, 1.0 + 1e-3);
  107. //boost::uniform_real<> random_location(-1e-3, -1e-3);
  108. //boost::uniform_real<> random_rotation(-1e-3, 1e-3);
  109. //boost::uniform_int<> random_points(3, 4);
  110. // This set (next 4 lines) are now solved ("distance-zero"/"merge iiii" problem)
  111. // 2009-12-03: 5,50 -> 2:1 000 000 wrong (2009-12-03)
  112. // 2010-01-16: solved (no errors in 10000000 calls)
  113. boost::uniform_real<> random_factor(0.3, 1.2);
  114. boost::uniform_real<> random_location(-20.0, +20.0); // -25.0, +25.0
  115. boost::uniform_real<> random_rotation(0, 0.5);
  116. boost::uniform_int<> random_points(5, 15);
  117. base_generator_type generator(seed);
  118. boost::variate_generator<base_generator_type&, boost::uniform_real<> >
  119. factor_generator(generator, random_factor);
  120. boost::variate_generator<base_generator_type&, boost::uniform_real<> >
  121. location_generator(generator, random_location);
  122. boost::variate_generator<base_generator_type&, boost::uniform_real<> >
  123. rotation_generator(generator, random_rotation);
  124. boost::variate_generator<base_generator_type&, boost::uniform_int<> >
  125. int_generator(generator, random_points);
  126. for(int i = 0; i < count; i++)
  127. {
  128. test_star_ellipse<T, Clockwise, Closed>(seed, i + 1,
  129. star_params(int_generator() * 2 + 1,
  130. factor_generator(), factor_generator(),
  131. location_generator(), location_generator(), rotation_generator()),
  132. star_params(int_generator() * 2 + 1,
  133. factor_generator(), factor_generator(),
  134. location_generator(), location_generator(), rotation_generator()),
  135. settings);
  136. }
  137. std::cout
  138. << "type: " << string_from_type<T>::name()
  139. << " time: " << t.elapsed() << std::endl;
  140. }
  141. template <bool Clockwise, bool Closed>
  142. void test_all(std::string const& type, int seed, int count, p_q_settings settings)
  143. {
  144. if (type == "float")
  145. {
  146. settings.tolerance = 1.0e-3;
  147. test_type<float, Clockwise, Closed>(seed, count, settings);
  148. }
  149. else if (type == "double")
  150. {
  151. test_type<double, Clockwise, Closed>(seed, count, settings);
  152. }
  153. #if defined(HAVE_TTMATH)
  154. else if (type == "ttmath")
  155. {
  156. test_type<ttmath_big, Clockwise, Closed>(seed, count, settings);
  157. }
  158. #endif
  159. }
  160. int main(int argc, char** argv)
  161. {
  162. try
  163. {
  164. namespace po = boost::program_options;
  165. po::options_description description("=== random_ellipses_stars ===\nAllowed options");
  166. int count = 1;
  167. int seed = static_cast<unsigned int>(std::time(0));
  168. std::string type = "float";
  169. bool ccw = false;
  170. bool open = false;
  171. p_q_settings settings;
  172. description.add_options()
  173. ("help", "Help message")
  174. ("seed", po::value<int>(&seed), "Initialization seed for random generator")
  175. ("count", po::value<int>(&count)->default_value(1), "Number of tests")
  176. ("diff", po::value<bool>(&settings.also_difference)->default_value(false), "Include testing on difference")
  177. ("ccw", po::value<bool>(&ccw)->default_value(false), "Counter clockwise polygons")
  178. ("open", po::value<bool>(&open)->default_value(false), "Open polygons")
  179. ("type", po::value<std::string>(&type)->default_value("float"), "Type (float,double)")
  180. ("wkt", po::value<bool>(&settings.wkt)->default_value(false), "Create a WKT of the inputs, for all tests")
  181. ("svg", po::value<bool>(&settings.svg)->default_value(false), "Create a SVG for all tests")
  182. ;
  183. po::variables_map varmap;
  184. po::store(po::parse_command_line(argc, argv, description), varmap);
  185. po::notify(varmap);
  186. if (varmap.count("help"))
  187. {
  188. std::cout << description << std::endl;
  189. return 1;
  190. }
  191. if (ccw && open)
  192. {
  193. test_all<false, false>(type, seed, count, settings);
  194. }
  195. else if (ccw)
  196. {
  197. test_all<false, true>(type, seed, count, settings);
  198. }
  199. else if (open)
  200. {
  201. test_all<true, false>(type, seed, count, settings);
  202. }
  203. else
  204. {
  205. test_all<true, true>(type, seed, count, settings);
  206. }
  207. }
  208. catch(std::exception const& e)
  209. {
  210. std::cout << "Exception " << e.what() << std::endl;
  211. }
  212. catch(...)
  213. {
  214. std::cout << "Other exception" << std::endl;
  215. }
  216. return 0;
  217. }