1717# include < boost/geometry/io/svg/svg_mapper.hpp>
1818#endif
1919
20+ #include " lambda_partition.hpp"
21+
2022#include < chrono>
2123#include < random>
2224#include < fstream>
@@ -43,112 +45,41 @@ struct ring_item
4345
4446BOOST_GEOMETRY_REGISTER_POINT_2D (point_item, double , cs::cartesian, x, y)
4547
46-
47- struct expand_for_point
48- {
49- template <typename Box, typename InputItem>
50- static inline void apply (Box& total, InputItem const & item)
51- {
52- bg::expand (total, item);
53- }
54- };
55-
56- struct overlaps_point
48+ #if defined(TEST_WITH_SVG)
49+ template <typename Points, typename Rings, typename Box, typename Boxes>
50+ void create_svg (std::size_t size, Points const & points, Rings const & rings, std::size_t index,
51+ Box const & box, int level,
52+ Boxes& boxes)
5753{
58- template <typename Box, typename InputItem>
59- static inline bool apply (Box const & box, InputItem const & item)
60- {
61- return ! bg::disjoint (item, box);
62- }
63- };
54+ std::ostringstream filename;
55+ filename << " partition_demo_" << std::setfill (' 0' ) << std::setw (3 ) << index << " _" << level << " .svg" ;
56+ std::ofstream svg (filename.str ());
6457
58+ bg::svg_mapper<point_item> mapper (svg, 800 , 800 );
6559
66- struct expand_for_ring
67- {
68- template <typename Box, typename InputItem>
69- static inline void apply (Box& total, InputItem const & item)
7060 {
71- bg::expand (total, item.box );
61+ point_item p;
62+ p.x = -1 ; p.y = -1 ; mapper.add (p);
63+ p.x = size + 1 ; p.y = size + 1 ; mapper.add (p);
7264 }
73- };
7465
75- struct overlaps_ring
76- {
77- template <typename Box, typename InputItem>
78- static inline bool apply (Box const & box, InputItem const & item)
66+ for (auto const & item : rings)
7967 {
80- typename bg::strategy::disjoint::services::default_strategy
81- <
82- Box, Box
83- >::type strategy;
84-
85- return ! bg::detail::disjoint::disjoint_box_box (box, item.box , strategy);
68+ mapper.map (item.ring , " opacity:0.6;fill:rgb(0,255,0);stroke:rgb(0,0,0);stroke-width:0.1" );
8669 }
87- };
88-
89- struct point_in_ring_visitor
90- {
91- std::size_t count = 0 ;
92-
93- template <typename Point, typename BoxItem>
94- inline bool apply (Point const & point, BoxItem const & ring_item)
70+ for (auto const & point : points)
9571 {
96- if (bg::within (point, ring_item.ring ))
97- {
98- count++;
99- }
100- return true ;
72+ mapper.map (point, " fill:rgb(0,0,255);stroke:rgb(0,0,100);stroke-width:0.1" , 3 );
10173 }
102- };
10374
104- #if defined(TEST_WITH_SVG)
105- template <typename Box, typename Points, typename Rings>
106- struct svg_visitor
107- {
108- std::vector<Box> boxes;
109- Points const & m_points;
110- Rings const & m_rings;
111- std::size_t m_size = 0 ;
112- std::size_t m_index = 0 ;
113-
114- svg_visitor (std::size_t size, Points const & points, Rings const & rings)
115- : m_points(points)
116- , m_rings(rings)
117- , m_size(size)
118- {}
119-
120- inline void apply (Box const & box, int level)
75+ for (auto const & b : boxes)
12176 {
122- std::ostringstream filename;
123- filename << " partition_demo_" << std::setfill (' 0' ) << std::setw (3 ) << m_index++ << " _" << level << " .svg" ;
124- std::ofstream svg (filename.str ());
125-
126- bg::svg_mapper<point_item> mapper (svg, 800 , 800 );
127-
128- {
129- point_item p;
130- p.x = -1 ; p.y = -1 ; mapper.add (p);
131- p.x = m_size + 1 ; p.y = m_size + 1 ; mapper.add (p);
132- }
133-
134- for (auto const & item : m_rings)
135- {
136- mapper.map (item.ring , " opacity:0.6;fill:rgb(0,255,0);stroke:rgb(0,0,0);stroke-width:0.1" );
137- }
138- for (auto const & point : m_points)
139- {
140- mapper.map (point, " fill:rgb(0,0,255);stroke:rgb(0,0,100);stroke-width:0.1" , 3 );
141- }
142-
143- for (auto const & b : boxes)
144- {
145- mapper.map (b, " fill:none;stroke-width:2;stroke:rgb(64,64,64);" );
146- }
147- mapper.map (box, " fill:none;stroke-width:4;stroke:rgb(255, 0, 0);" );
148-
149- boxes.push_back (box);
77+ mapper.map (b, " fill:none;stroke-width:2;stroke:rgb(64,64,64);" );
15078 }
151- };
79+ mapper.map (box, " fill:none;stroke-width:4;stroke:rgb(255, 0, 0);" );
80+
81+ boxes.push_back (box);
82+ }
15283#endif
15384
15485
@@ -161,7 +92,7 @@ void fill_points(Collection& collection, std::size_t size, std::size_t count)
16192 std::uniform_real_distribution<double > uniform_dist (0 , size - 1 );
16293 int const mean_x = uniform_dist (rde);
16394 int const mean_y = uniform_dist (rde);
164-
95+
16596 // Generate a normal distribution around these means
16697 std::seed_seq seed2{rd (), rd (), rd (), rd (), rd (), rd (), rd (), rd ()};
16798 std::mt19937 e2 (seed2);
@@ -302,7 +233,7 @@ void call_within(std::size_t size, std::size_t count)
302233 auto report = [&points, &rings](const char * title, auto const & start, std::size_t within_count)
303234 {
304235 auto const finish = std::chrono::steady_clock::now ();
305- double const elapsed
236+ double const elapsed
306237 = std::chrono::duration_cast<std::chrono::nanoseconds>(finish - start).count ();
307238 std::cout << title << " time: " << std::setprecision (6 )
308239 << elapsed / 1000000.0 << " ms" << std::endl;
@@ -311,27 +242,44 @@ void call_within(std::size_t size, std::size_t count)
311242 return elapsed;
312243 };
313244
314- point_in_ring_visitor count_visitor;
315- {
316245#if defined(TEST_WITH_SVG)
317-
318- using partition_box_visitor_type = svg_visitor<box_type, std::vector<point_item>, std::vector<ring_item<ring_type>>>;
319- partition_box_visitor_type partition_box_visitor (size, points, rings);
246+ std::size_t index = 0 ;
247+ std::vector<box_type> boxes;
248+ auto box_visitor = [&](auto const & box, int level)
249+ {
250+ create_svg (size, points, rings, index++, box, level, boxes);
251+ };
320252#else
321- using partition_box_visitor_type = bg::detail::partition::visit_no_policy;
322- partition_box_visitor_type partition_box_visitor;
253+ auto box_visitor = [&](auto const & , int ) {};
323254#endif
324255
256+ std::size_t partition_count = 0 ;
257+ {
325258 auto const start = std::chrono::steady_clock::now ();
326259
327- bg::partition
260+ typename bg::strategy::disjoint::services::default_strategy
328261 <
329- box_type,
330- bg::detail::partition::include_all_policy,
331- bg::detail::partition::include_all_policy
332- >::apply (points, rings, count_visitor, expand_for_point (), overlaps_point (),
333- expand_for_ring (), overlaps_ring (), 16 , partition_box_visitor);
334- report (" Partition" , start, count_visitor.count );
262+ box_type, box_type
263+ >::type strategy;
264+
265+ bg::experimental::partition<box_type>(points,
266+ rings,
267+ [](auto & box, auto const & point) { bg::expand (box, point); },
268+ [](auto const & box, auto const & point) { return ! bg::disjoint (point, box); },
269+ [](auto & box, auto const & item) { bg::expand (box, item.box ); },
270+ [&strategy](auto const & box, auto const & item) { return ! bg::disjoint (box, item.box , strategy); },
271+ [&partition_count](auto const & p, auto const & ri)
272+ {
273+ if (bg::within (p, ri.ring ))
274+ {
275+ partition_count++;
276+ }
277+ return true ;
278+ },
279+ box_visitor
280+ );
281+
282+ report (" Partition" , start, partition_count);
335283 }
336284
337285 {
@@ -350,7 +298,7 @@ void call_within(std::size_t size, std::size_t count)
350298 }
351299 report (" Quadratic loop" , start, count);
352300
353- if (count != count_visitor. count )
301+ if (count != partition_count )
354302 {
355303 std::cerr << " ERROR: counts are not equal" << std::endl;
356304 }
0 commit comments