contrek 1.3.3 → 1.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +3 -0
  3. data/Gemfile.lock +3 -1
  4. data/README.md +28 -28
  5. data/contrek.gemspec +1 -0
  6. data/ext/cpp_polygon_finder/PolygonFinder/src/ContrekApi.h +2 -0
  7. data/ext/cpp_polygon_finder/PolygonFinder/src/Tests.cpp +0 -2
  8. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/FinderUtils.cpp +11 -5
  9. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Node.cpp +8 -10
  10. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Node.h +4 -1
  11. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/NodeCluster.cpp +114 -42
  12. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/NodeCluster.h +1 -1
  13. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/PolygonFinder.h +2 -1
  14. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cluster.cpp +1 -1
  15. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cursor.cpp +66 -116
  16. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cursor.h +1 -1
  17. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Finder.cpp +1 -0
  18. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Part.cpp +2 -87
  19. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Part.h +1 -13
  20. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/PartPool.cpp +0 -1
  21. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Partitionable.cpp +1 -57
  22. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Partitionable.h +1 -4
  23. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Queueable.h +31 -17
  24. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Sequence.cpp +0 -16
  25. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Sequence.h +0 -9
  26. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Tile.cpp +1 -1
  27. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/DouglasPeuckerReducer.cpp +177 -0
  28. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/DouglasPeuckerReducer.h +52 -0
  29. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/RasterReducer.cpp +109 -0
  30. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/RasterReducer.h +32 -0
  31. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/VisvalingamReducer.h +6 -1
  32. data/ext/cpp_polygon_finder/cpp_polygon_finder.cpp +4 -0
  33. data/lib/contrek/bitmaps/painting.rb +27 -10
  34. data/lib/contrek/bitmaps/png_bitmap.rb +3 -0
  35. data/lib/contrek/bitmaps/rendering.rb +75 -0
  36. data/lib/contrek/finder/concurrent/cursor.rb +62 -84
  37. data/lib/contrek/finder/concurrent/finder.rb +2 -1
  38. data/lib/contrek/finder/concurrent/part.rb +4 -77
  39. data/lib/contrek/finder/concurrent/partitionable.rb +1 -58
  40. data/lib/contrek/finder/concurrent/queueable.rb +23 -5
  41. data/lib/contrek/finder/concurrent/sequence.rb +0 -15
  42. data/lib/contrek/finder/concurrent/tile.rb +1 -1
  43. data/lib/contrek/finder/node.rb +26 -8
  44. data/lib/contrek/finder/node_cluster.rb +91 -37
  45. data/lib/contrek/finder/polygon_finder.rb +1 -1
  46. data/lib/contrek/reducers/douglas_peucker_reducer.rb +191 -0
  47. data/lib/contrek/reducers/raster_reducer.rb +72 -0
  48. data/lib/contrek/version.rb +1 -1
  49. data/lib/contrek.rb +3 -0
  50. metadata +23 -2
@@ -32,7 +32,9 @@ module Contrek
32
32
  path_sequences do |seq|
33
33
  Contrek::Reducers::UniqReducer.new(points: seq).reduce! if @options[:compress].has_key?(:uniq)
34
34
  Contrek::Reducers::LinearReducer.new(points: seq, options: @options[:compress][:linear]).reduce! if @options[:compress].has_key?(:linear)
35
+ Contrek::Reducers::RasterReducer.new(points: seq, options: @options).reduce! if @options[:compress].has_key?(:raster)
35
36
  Contrek::Reducers::VisvalingamReducer.new(points: seq, options: @options[:compress][:visvalingam]).reduce! if @options[:compress].has_key?(:visvalingam)
37
+ Contrek::Reducers::DouglasPeuckerReducer.new(points: seq).reduce! if @options[:compress].has_key?(:douglas_peucker)
36
38
  end
37
39
  end
38
40
 
@@ -70,16 +72,44 @@ module Contrek
70
72
  else
71
73
  root_node.get_tangent_node_by_virtual_index(root_node.tangs_sequence.first)
72
74
  end
73
- if !next_node.nil?
75
+
76
+ if next_node
77
+ beginning_point = (versus == :a) ? root_node.nw_point : root_node.ne_point
78
+ @sequence_coords << beginning_point
79
+ bounds.expand(**beginning_point)
80
+
74
81
  coord = next_node.coords_entering_to(root_node, VERSUS_INVERTER[versus], Contrek::Finder::Node::OUTER)
75
82
  @sequence_coords << coord
76
- bounds.expand(x: coord[:x], y: coord[:y])
83
+ bounds.expand(**coord)
84
+ end
85
+
86
+ plot_node(next_node, root_node, bounds, versus) if @nodes > 0 && !next_node.nil?
87
+
88
+ if next_node.nil?
89
+ if versus == :a
90
+ nw_point = root_node.nw_point
91
+ @sequence_coords << nw_point
92
+ bounds.expand(**nw_point)
93
+ @sequence_coords << root_node.sw_point
94
+ se_point = root_node.se_point
95
+ @sequence_coords << se_point
96
+ bounds.expand(**se_point)
97
+ @sequence_coords << root_node.ne_point
98
+ else
99
+ ne_point = root_node.ne_point
100
+ @sequence_coords << ne_point
101
+ bounds.expand(**ne_point)
102
+ @sequence_coords << root_node.se_point
103
+ sw_point = root_node.sw_point
104
+ @sequence_coords << sw_point
105
+ bounds.expand(**sw_point)
106
+ @sequence_coords << root_node.nw_point
107
+ end
77
108
  end
78
- plot_node(next_node, root_node, bounds, versus, @options[:strict_bounds]) if @nodes > 0 && !next_node.nil?
79
109
 
80
110
  draw_sequence(bitmap, "X") unless bitmap.nil?
81
111
 
82
- if @sequence_coords.size >= 2
112
+ if @sequence_coords.any?
83
113
  @polygons << {outer: @sequence_coords, inner: [], bounds: (bounds.to_h if @options[:bounds])}.compact
84
114
  @sequences << @plot_sequence
85
115
 
@@ -117,10 +147,11 @@ module Contrek
117
147
 
118
148
  if !next_node.nil?
119
149
  @sequence_coords << next_node.coords_entering_to(first, inner_v, Contrek::Finder::Node::INNER)
150
+ last_node = plot_inner_node(next_node, inner_v, first, root_node)
151
+ last_coord = last_node.coords_entering_to(first, VERSUS_INVERTER[inner_v], Contrek::Finder::Node::INNER)
152
+ @sequence_coords << last_coord if @sequence_coords.last != last_coord
120
153
  end
121
154
 
122
- plot_inner_node(next_node, inner_v, first, root_node, options[:strict_bounds]) if !next_node.nil?
123
-
124
155
  draw_sequence(bitmap, "+") unless bitmap.nil?
125
156
 
126
157
  @polygons.last[:inner] << @sequence_coords
@@ -194,7 +225,7 @@ module Contrek
194
225
  # inner way
195
226
  # nodes in @plot_sequence
196
227
  # coordinates in @sequence_coords
197
- def plot_inner_node(node, versus, stop_at, start_node, strict_bounds = false)
228
+ def plot_inner_node(node, versus, stop_at, start_node)
198
229
  node.outer_index = start_node.outer_index
199
230
  @root_nodes.delete(node)
200
231
  @inner_plot.delete(node)
@@ -214,16 +245,25 @@ module Contrek
214
245
  virtual_index = node.tangs_sequence.send((versus == :a) ? :first : :last)
215
246
  plot = (node.get_tangent_node_by_virtual_index(virtual_index) == next_node)
216
247
  end
248
+
217
249
  if plot
218
- @sequence_coords << last_node.coords_entering_to(node, VERSUS_INVERTER[versus], Contrek::Finder::Node::INNER)
219
- if node != start_node
220
- if last_node.y == next_node.y
221
- @sequence_coords << next_node.coords_entering_to(node, versus, Contrek::Finder::Node::INNER)
250
+ first_point = last_node.coords_entering_to(node, VERSUS_INVERTER[versus], Contrek::Finder::Node::INNER)
251
+ @sequence_coords << first_point if @sequence_coords.last != first_point
252
+ if next_node.y == last_node.y
253
+ if next_node.y < node.y
254
+ pt_a, pt_b = node.sw_point, node.se_point
255
+ else
256
+ pt_a, pt_b = node.ne_point, node.nw_point
257
+ end
258
+ if versus == :o
259
+ @sequence_coords << pt_a
260
+ @sequence_coords << pt_b
261
+ else
262
+ @sequence_coords << pt_b
263
+ @sequence_coords << pt_a
222
264
  end
223
265
  end
224
- elsif strict_bounds
225
- @sequence_coords << {y: node.y, x: (first_is_max ? last_node.max_x : last_node.min_x)}
226
- @sequence_coords << {y: node.y, x: (first_is_max ? next_node.min_x : next_node.max_x)}
266
+ @sequence_coords << next_node.coords_entering_to(node, versus, Contrek::Finder::Node::INNER)
227
267
  end
228
268
 
229
269
  if node.track_uncomplete
@@ -232,12 +272,12 @@ module Contrek
232
272
  @inner_new.delete(node)
233
273
  end
234
274
 
235
- return if next_node == stop_at
236
- plot_inner_node(next_node, versus, stop_at, start_node, strict_bounds)
275
+ return node if next_node == stop_at
276
+ plot_inner_node(next_node, versus, stop_at, start_node)
237
277
  end
238
278
 
239
279
  # contour tracing core logic loop
240
- def plot_node(node, start_node, bounds, versus = :a, strict_bounds = false)
280
+ def plot_node(node, start_node, bounds, versus = :a)
241
281
  @root_nodes.delete(node)
242
282
 
243
283
  node.outer_index = start_node.outer_index
@@ -252,32 +292,47 @@ module Contrek
252
292
  plot = (node.get_tangent_node_by_virtual_index(virtual_index) == next_node)
253
293
  end
254
294
 
255
- # coord
256
295
  if plot
257
- c = last_node.coords_entering_to(node, versus, Contrek::Finder::Node::OUTER)
258
- @sequence_coords << c
259
- bounds.expand(x: c[:x], y: c[:y])
296
+ start_coord = last_node.coords_entering_to(node, versus, Contrek::Finder::Node::OUTER)
297
+ if @sequence_coords.last != start_coord
298
+ @sequence_coords << start_coord
299
+ bounds.expand(**start_coord)
300
+ end
301
+
302
+ final_step = node == start_node && node.track_complete
303
+ if next_node.y == last_node.y
304
+ if next_node.y < node.y
305
+ pt_a, pt_b = node.se_point, node.sw_point
306
+ else
307
+ pt_a, pt_b = node.nw_point, node.ne_point
308
+ end
309
+ first = (versus == :o) ? pt_a : pt_b
310
+ second = (versus == :o) ? pt_b : pt_a
311
+ @sequence_coords << first
312
+ bounds.expand(**first)
313
+ unless final_step
314
+ @sequence_coords << second
315
+ bounds.expand(**second)
316
+ end
317
+ end
318
+
319
+ unless final_step
320
+ end_coord = next_node.coords_entering_to(node, VERSUS_INVERTER[versus], Contrek::Finder::Node::OUTER)
321
+ @sequence_coords << end_coord
322
+ bounds.expand(**end_coord)
323
+ end
324
+
260
325
  if node != start_node
261
326
  @inner_plot.contains(node) ? @inner_plot.delete(node) : @inner_plot << node
262
327
  if last_node.y == next_node.y
263
- c = next_node.coords_entering_to(node, VERSUS_INVERTER[versus], Contrek::Finder::Node::OUTER)
264
- @sequence_coords << c
265
- bounds.expand(x: c[:x], y: c[:y])
266
328
  @inner_plot.contains(node) ? @inner_plot.delete(node) : @inner_plot << node
267
329
  end
268
330
  end
269
- elsif strict_bounds
270
- is_down = node.y > last_node.y
271
- is_a = (versus == :a)
272
- @sequence_coords << {y: node.y, x: ((is_down == is_a) ? last_node.min_x : last_node.max_x)}
273
- @sequence_coords << {y: node.y, x: ((is_down == is_a) ? next_node.max_x : next_node.min_x)}
274
331
  end
275
332
  # exit if root_node
333
+ return if node == start_node && node.track_complete
276
334
 
277
- if node == start_node
278
- return if node.track_complete
279
- end
280
- plot_node(next_node, start_node, bounds, versus, strict_bounds)
335
+ plot_node(next_node, start_node, bounds, versus)
281
336
  end
282
337
 
283
338
  def add_node(node, offset)
@@ -295,15 +350,15 @@ module Contrek
295
350
  index = 0
296
351
  loop do
297
352
  up_node = up_nodes[index]
298
- if (up_node.max_x + offset) >= node.min_x
299
- if (up_node.min_x - offset) <= node.max_x
353
+ if ((up_node.max_x - 1) + offset) >= node.min_x
354
+ if (up_node.min_x - offset) <= (node.max_x - 1)
300
355
  node.add_intersection(up_node, index)
301
356
  up_node.add_intersection(node, node.abs_x_index)
302
357
  end
303
358
  return if (index += 1) == up_nodes_count
304
359
  loop do
305
360
  up_node = up_nodes[index]
306
- if (up_node.min_x - offset) <= node.max_x
361
+ if (up_node.min_x - offset) <= (node.max_x - 1)
307
362
  node.add_intersection(up_node, index)
308
363
  up_node.add_intersection(node, node.abs_x_index)
309
364
  else
@@ -316,7 +371,6 @@ module Contrek
316
371
  break if (index += 1) == up_nodes_count
317
372
  end
318
373
  end
319
-
320
374
  end
321
375
  end
322
376
  end
@@ -6,7 +6,7 @@ module Contrek
6
6
  module Finder
7
7
  class PolygonFinder
8
8
  def initialize(bitmap, matcher, test_bitmap = nil, options = {})
9
- @options = {versus: :a, strict_bounds: false}.merge(options)
9
+ @options = {versus: :a}.merge(options)
10
10
  sanitize_options
11
11
  @source_bitmap = bitmap
12
12
  @matcher = matcher
@@ -0,0 +1,191 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Contrek
4
+ module Reducers
5
+ class DouglasPeuckerReducer < Reducer
6
+ TOLERANCE_SQUARED = 1.0
7
+
8
+ def reduce!
9
+ count = @points.length
10
+ return @points if count < 4
11
+
12
+ first_index = extreme_index_by_x
13
+ second_index = farthest_index_from(first_index)
14
+
15
+ return @points if second_index == first_index
16
+
17
+ keep = Array.new(count, false)
18
+ keep[first_index] = true
19
+ keep[second_index] = true
20
+
21
+ simplify_arc!(first_index, second_index, keep)
22
+ simplify_arc!(second_index, first_index, keep)
23
+
24
+ compact_ring!(keep)
25
+ end
26
+
27
+ private
28
+
29
+ def extreme_index_by_x
30
+ points = @points
31
+ index = 0
32
+ best = 0
33
+ best_x = points[0][:x]
34
+
35
+ while (index += 1) < points.length
36
+ x = points[index][:x]
37
+
38
+ if x < best_x
39
+ best_x = x
40
+ best = index
41
+ end
42
+ end
43
+
44
+ best
45
+ end
46
+
47
+ def farthest_index_from(origin_index)
48
+ points = @points
49
+ origin = points[origin_index]
50
+
51
+ ox = origin[:x]
52
+ oy = origin[:y]
53
+
54
+ best_index = origin_index
55
+ best_distance = -1
56
+
57
+ index = 0
58
+
59
+ while index < points.length
60
+ dx = points[index][:x] - ox
61
+ dy = points[index][:y] - oy
62
+ distance = dx * dx + dy * dy
63
+
64
+ if distance > best_distance
65
+ best_distance = distance
66
+ best_index = index
67
+ end
68
+
69
+ index += 1
70
+ end
71
+
72
+ best_index
73
+ end
74
+
75
+ def simplify_arc!(first_index, last_index, keep)
76
+ count = @points.length
77
+ stack = [first_index, last_index]
78
+
79
+ until stack.empty?
80
+ last = stack.pop
81
+ first = stack.pop
82
+
83
+ split = farthest_on_arc(first, last, count)
84
+ next unless split
85
+
86
+ keep[split] = true
87
+
88
+ stack << first << split if next_index(first, count) != split
89
+ stack << split << last if next_index(split, count) != last
90
+ end
91
+ end
92
+
93
+ def farthest_on_arc(first_index, last_index, count)
94
+ points = @points
95
+
96
+ first = points[first_index]
97
+ last = points[last_index]
98
+
99
+ ax = first[:x]
100
+ ay = first[:y]
101
+ bx = last[:x]
102
+ by = last[:y]
103
+
104
+ abx = bx - ax
105
+ aby = by - ay
106
+ length_squared = abx * abx + aby * aby
107
+
108
+ max_distance = TOLERANCE_SQUARED
109
+ split_index = nil
110
+ index = next_index(first_index, count)
111
+
112
+ while index != last_index
113
+ point = points[index]
114
+
115
+ distance = if length_squared.zero?
116
+ dx = point[:x] - ax
117
+ dy = point[:y] - ay
118
+ dx * dx + dy * dy
119
+ else
120
+ point_segment_distance_squared(
121
+ point[:x],
122
+ point[:y],
123
+ ax,
124
+ ay,
125
+ bx,
126
+ by,
127
+ abx,
128
+ aby,
129
+ length_squared
130
+ )
131
+ end
132
+
133
+ if distance > max_distance
134
+ max_distance = distance
135
+ split_index = index
136
+ end
137
+
138
+ index = next_index(index, count)
139
+ end
140
+
141
+ split_index
142
+ end
143
+
144
+ def point_segment_distance_squared(
145
+ px, py,
146
+ ax, ay,
147
+ bx, by,
148
+ abx, aby,
149
+ length_squared
150
+ )
151
+ apx = px - ax
152
+ apy = py - ay
153
+
154
+ dot = apx * abx + apy * aby
155
+
156
+ if dot <= 0
157
+ apx * apx + apy * apy
158
+ elsif dot >= length_squared
159
+ bpx = px - bx
160
+ bpy = py - by
161
+ bpx * bpx + bpy * bpy
162
+ else
163
+ cross = apx * aby - apy * abx
164
+ (cross * cross).fdiv(length_squared)
165
+ end
166
+ end
167
+
168
+ def next_index(index, count)
169
+ (index + 1 == count) ? 0 : index + 1
170
+ end
171
+
172
+ def compact_ring!(keep)
173
+ points = @points
174
+ read_index = 0
175
+ write_index = 0
176
+
177
+ while read_index < points.length
178
+ if keep[read_index]
179
+ points[write_index] = points[read_index]
180
+ write_index += 1
181
+ end
182
+
183
+ read_index += 1
184
+ end
185
+
186
+ points.slice!(write_index, points.length - write_index)
187
+ points
188
+ end
189
+ end
190
+ end
191
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Contrek
4
+ module Reducers
5
+ class RasterReducer < Reducer
6
+ def reduce!
7
+ versus = @opts[:versus]
8
+ to_raster_polygon!(@points, versus)
9
+ end
10
+
11
+ private
12
+
13
+ def to_raster_polygon!(points, versus)
14
+ n = points.size
15
+ return points if n.zero?
16
+
17
+ outer = versus == :o
18
+ first_x = points[0][:x]
19
+ first_y = points[0][:y]
20
+ prev_x = points[-1][:x]
21
+ prev_y = points[-1][:y]
22
+ points.each_index do |i|
23
+ curr_x = points[i][:x]
24
+ curr_y = points[i][:y]
25
+ if i + 1 < n
26
+ next_x = points[i + 1][:x]
27
+ next_y = points[i + 1][:y]
28
+ else
29
+ next_x = first_x
30
+ next_y = first_y
31
+ end
32
+ in_side = segment_pole(
33
+ curr_x - prev_x,
34
+ curr_y - prev_y,
35
+ outer
36
+ )
37
+ out_side = segment_pole(
38
+ next_x - curr_x,
39
+ next_y - curr_y,
40
+ outer
41
+ )
42
+ x = curr_x
43
+ y = curr_y
44
+ [in_side, out_side].uniq.each do |side|
45
+ case side
46
+ when :south then y -= 1
47
+ when :east then x -= 1
48
+ end
49
+ end
50
+ points[i][:x] = x
51
+ points[i][:y] = y
52
+ prev_x = curr_x
53
+ prev_y = curr_y
54
+ end
55
+ points
56
+ end
57
+
58
+ def segment_pole(dx, dy, clockwise)
59
+ sx = dx <=> 0
60
+ sy = dy <=> 0
61
+ case [sx, sy]
62
+ when [0, 1] then clockwise ? :east : :west
63
+ when [1, 0] then clockwise ? :north : :south
64
+ when [0, -1] then clockwise ? :west : :east
65
+ when [-1, 0] then clockwise ? :south : :north
66
+ else
67
+ raise ArgumentError, "Non-axial segment dx=#{dx} dy=#{dy}!"
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Contrek
4
- VERSION = "1.3.3"
4
+ VERSION = "1.3.5"
5
5
  end
data/lib/contrek.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "contrek/version"
4
4
  require "contrek/bitmaps/painting"
5
+ require "contrek/bitmaps/rendering"
5
6
  require "contrek/bitmaps/bitmap"
6
7
  require "contrek/bitmaps/chunky_bitmap"
7
8
  require "contrek/bitmaps/png_bitmap"
@@ -51,6 +52,8 @@ require "contrek/reducers/reducer"
51
52
  require "contrek/reducers/linear_reducer"
52
53
  require "contrek/reducers/uniq_reducer"
53
54
  require "contrek/reducers/visvalingam_reducer"
55
+ require "contrek/reducers/douglas_peucker_reducer"
56
+ require "contrek/reducers/raster_reducer"
54
57
  require "cpp_polygon_finder"
55
58
  require "contrek/cpp/cpp_concurrent_finder"
56
59
  require "contrek/cpp/cpp_concurrent_merger"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: contrek
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.3
4
+ version: 1.3.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emanuele Cesaroni
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-06-28 00:00:00.000000000 Z
11
+ date: 2026-07-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -78,6 +78,20 @@ dependencies:
78
78
  - - ">="
79
79
  - !ruby/object:Gem::Version
80
80
  version: 1.7.2
81
+ - !ruby/object:Gem::Dependency
82
+ name: ruby2d
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - "~>"
86
+ - !ruby/object:Gem::Version
87
+ version: '0.12'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - "~>"
93
+ - !ruby/object:Gem::Version
94
+ version: '0.12'
81
95
  - !ruby/object:Gem::Dependency
82
96
  name: chunky_png
83
97
  requirement: !ruby/object:Gem::Requirement
@@ -234,8 +248,12 @@ files:
234
248
  - ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/RGBNotMatcher.h
235
249
  - ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/ValueNotMatcher.cpp
236
250
  - ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/ValueNotMatcher.h
251
+ - ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/DouglasPeuckerReducer.cpp
252
+ - ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/DouglasPeuckerReducer.h
237
253
  - ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/LinearReducer.cpp
238
254
  - ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/LinearReducer.h
255
+ - ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/RasterReducer.cpp
256
+ - ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/RasterReducer.h
239
257
  - ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/Reducer.cpp
240
258
  - ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/Reducer.h
241
259
  - ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/UniqReducer.cpp
@@ -251,6 +269,7 @@ files:
251
269
  - lib/contrek/bitmaps/painting.rb
252
270
  - lib/contrek/bitmaps/png_bitmap.rb
253
271
  - lib/contrek/bitmaps/raw_bitmap.rb
272
+ - lib/contrek/bitmaps/rendering.rb
254
273
  - lib/contrek/bitmaps/rgb_color.rb
255
274
  - lib/contrek/bitmaps/rgb_cpp_color.rb
256
275
  - lib/contrek/bitmaps/sample_generator.rb
@@ -299,7 +318,9 @@ files:
299
318
  - lib/contrek/matchers/matcher.rb
300
319
  - lib/contrek/matchers/matcher_hsb.rb
301
320
  - lib/contrek/matchers/value_not_matcher.rb
321
+ - lib/contrek/reducers/douglas_peucker_reducer.rb
302
322
  - lib/contrek/reducers/linear_reducer.rb
323
+ - lib/contrek/reducers/raster_reducer.rb
303
324
  - lib/contrek/reducers/reducer.rb
304
325
  - lib/contrek/reducers/uniq_reducer.rb
305
326
  - lib/contrek/reducers/visvalingam_reducer.rb