17
17
# include < boost/geometry/io/svg/svg_mapper.hpp>
18
18
#endif
19
19
20
+ #include " lambda_partition.hpp"
21
+
20
22
#include < chrono>
21
23
#include < random>
22
24
#include < fstream>
@@ -43,112 +45,41 @@ struct ring_item
43
45
44
46
BOOST_GEOMETRY_REGISTER_POINT_2D (point_item, double , cs::cartesian, x, y)
45
47
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)
57
53
{
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 ());
64
57
58
+ bg::svg_mapper<point_item> mapper (svg, 800 , 800 );
65
59
66
- struct expand_for_ring
67
- {
68
- template <typename Box, typename InputItem>
69
- static inline void apply (Box& total, InputItem const & item)
70
60
{
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);
72
64
}
73
- };
74
65
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)
79
67
{
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" );
86
69
}
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)
95
71
{
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 );
101
73
}
102
- };
103
74
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)
121
76
{
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);" );
150
78
}
151
- };
79
+ mapper.map (box, " fill:none;stroke-width:4;stroke:rgb(255, 0, 0);" );
80
+
81
+ boxes.push_back (box);
82
+ }
152
83
#endif
153
84
154
85
@@ -161,7 +92,7 @@ void fill_points(Collection& collection, std::size_t size, std::size_t count)
161
92
std::uniform_real_distribution<double > uniform_dist (0 , size - 1 );
162
93
int const mean_x = uniform_dist (rde);
163
94
int const mean_y = uniform_dist (rde);
164
-
95
+
165
96
// Generate a normal distribution around these means
166
97
std::seed_seq seed2{rd (), rd (), rd (), rd (), rd (), rd (), rd (), rd ()};
167
98
std::mt19937 e2 (seed2);
@@ -302,7 +233,7 @@ void call_within(std::size_t size, std::size_t count)
302
233
auto report = [&points, &rings](const char * title, auto const & start, std::size_t within_count)
303
234
{
304
235
auto const finish = std::chrono::steady_clock::now ();
305
- double const elapsed
236
+ double const elapsed
306
237
= std::chrono::duration_cast<std::chrono::nanoseconds>(finish - start).count ();
307
238
std::cout << title << " time: " << std::setprecision (6 )
308
239
<< elapsed / 1000000.0 << " ms" << std::endl;
@@ -311,27 +242,44 @@ void call_within(std::size_t size, std::size_t count)
311
242
return elapsed;
312
243
};
313
244
314
- point_in_ring_visitor count_visitor;
315
- {
316
245
#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
+ };
320
252
#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 ) {};
323
254
#endif
324
255
256
+ std::size_t partition_count = 0 ;
257
+ {
325
258
auto const start = std::chrono::steady_clock::now ();
326
259
327
- bg::partition
260
+ typename bg::strategy::disjoint::services::default_strategy
328
261
<
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);
335
283
}
336
284
337
285
{
@@ -350,7 +298,7 @@ void call_within(std::size_t size, std::size_t count)
350
298
}
351
299
report (" Quadratic loop" , start, count);
352
300
353
- if (count != count_visitor. count )
301
+ if (count != partition_count )
354
302
{
355
303
std::cerr << " ERROR: counts are not equal" << std::endl;
356
304
}
0 commit comments