contrek 1.1.9 → 1.2.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/Gemfile.lock +1 -1
- data/README.md +30 -9
- data/Rakefile +1 -1
- data/ext/cpp_polygon_finder/PolygonFinder/CMakeLists.txt +10 -12
- data/ext/cpp_polygon_finder/PolygonFinder/examples/example.cpp +6 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/Tests.cpp +1 -1
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Node.cpp +2 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Node.h +36 -2
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/NodeCluster.cpp +4 -4
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cluster.cpp +2 -3
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cursor.cpp +66 -158
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cursor.h +0 -2
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/EndPoint.h +4 -2
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Hub.cpp +2 -2
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Hub.h +1 -5
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Part.cpp +0 -13
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Part.h +1 -3
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Partitionable.cpp +0 -128
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Partitionable.h +0 -6
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Polyline.cpp +0 -50
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Polyline.h +2 -8
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Position.cpp +22 -3
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Queueable.h +1 -57
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Tile.cpp +0 -12
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Tile.h +0 -3
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/VerticalMerger.cpp +11 -3
- data/ext/cpp_polygon_finder/cpp_polygon_finder.cpp +10 -0
- data/lib/contrek/finder/concurrent/cluster.rb +2 -3
- data/lib/contrek/finder/concurrent/cursor.rb +56 -120
- data/lib/contrek/finder/concurrent/end_point.rb +2 -0
- data/lib/contrek/finder/concurrent/hub.rb +1 -1
- data/lib/contrek/finder/concurrent/part.rb +2 -20
- data/lib/contrek/finder/concurrent/partitionable.rb +0 -81
- data/lib/contrek/finder/concurrent/polyline.rb +3 -47
- data/lib/contrek/finder/concurrent/position.rb +8 -2
- data/lib/contrek/finder/concurrent/queueable.rb +0 -41
- data/lib/contrek/finder/concurrent/tile.rb +0 -4
- data/lib/contrek/finder/concurrent/vertical_merger.rb +9 -5
- data/lib/contrek/version.rb +1 -1
- metadata +3 -3
- /data/{LICENSE-MIT.md → lib/LICENSE-MIT.md} +0 -0
|
@@ -39,74 +39,39 @@ module Contrek
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
def join_inners!(outer_seq)
|
|
42
|
-
|
|
43
|
-
missing_shapes = []
|
|
44
|
-
@cluster.tiles.each do |tile|
|
|
45
|
-
tile.shapes.each do |shape|
|
|
46
|
-
next if shape.outer_polyline.on?(Polyline::TRACKED_OUTER) ||
|
|
47
|
-
shape.outer_polyline.on?(Polyline::TRACKED_INNER) ||
|
|
48
|
-
!shape.outer_polyline.boundary? ||
|
|
49
|
-
@shapes_sequence.include?(shape)
|
|
50
|
-
missing_shapes << shape
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
if missing_shapes.any?
|
|
55
|
-
to_delay_shapes = connect_missings(@shapes_sequence, missing_shapes)
|
|
56
|
-
if to_delay_shapes.any?
|
|
57
|
-
connect_missings(to_delay_shapes, missing_shapes)
|
|
58
|
-
while to_delay_shapes.any?
|
|
59
|
-
to_delay_shapes = connect_missings(@shapes_sequence, to_delay_shapes)
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
retme = collect_inner_sequences(outer_seq)
|
|
42
|
+
return_inner_polylines = []
|
|
65
43
|
|
|
66
|
-
@shapes_sequence.
|
|
67
|
-
shape.outer_polyline.turn_on(Polyline::TRACKED_INNER)
|
|
68
|
-
end
|
|
69
|
-
retme
|
|
70
|
-
end
|
|
44
|
+
@processing_shapes = @shapes_sequence.to_a
|
|
71
45
|
|
|
72
|
-
|
|
46
|
+
@processing_shapes.each do |shape|
|
|
47
|
+
polyline = shape.outer_polyline
|
|
48
|
+
polyline.parts.each do |part|
|
|
49
|
+
if part.innerable?
|
|
50
|
+
all_parts = []
|
|
51
|
+
bounds = {min: polyline.max_y, max: 0}
|
|
52
|
+
traverse_inner(part, all_parts, bounds)
|
|
53
|
+
range_of_bounds = (bounds[:min]..bounds[:max])
|
|
73
54
|
|
|
74
|
-
|
|
75
|
-
|
|
55
|
+
retme_sequence = Sequence.new
|
|
56
|
+
all_parts.each do |part|
|
|
57
|
+
part.touch!
|
|
58
|
+
retme_sequence.move_from(part) do |position|
|
|
59
|
+
next false if part.is?(Part::ADDED) && !(range_of_bounds === position.payload[:y])
|
|
76
60
|
|
|
77
|
-
|
|
78
|
-
polyline = shape.outer_polyline
|
|
79
|
-
missing_shapes.each do |missing_shape|
|
|
80
|
-
missing_outer_polyline = missing_shape.outer_polyline
|
|
81
|
-
next if (polyline.mixed_tile_origin == false && missing_outer_polyline.tile == polyline.tile) || # accepts only other side ones
|
|
82
|
-
missing_outer_polyline.on?(Polyline::TRACKED_OUTER) ||
|
|
83
|
-
polyline == missing_outer_polyline ||
|
|
84
|
-
!polyline.vert_intersect?(missing_outer_polyline)
|
|
85
|
-
|
|
86
|
-
if (intersection = polyline.intersection(missing_outer_polyline)).any?
|
|
87
|
-
inject_sequences_left, inject_sequences_right = polyline.sew!(intersection, missing_outer_polyline)
|
|
88
|
-
if inject_sequences_left.nil?
|
|
89
|
-
delay_shapes << missing_shape
|
|
90
|
-
next
|
|
91
|
-
end
|
|
92
|
-
combine!(inject_sequences_right, inject_sequences_left).each do |sewn_sequence|
|
|
93
|
-
sewn_sequence.uniq!
|
|
94
|
-
if sewn_sequence.size > 1 && sewn_sequence.map { |c| c[:x] }.uniq.size > 1 # only areas
|
|
95
|
-
@orphan_inners << InnerPolyline.new(shape: shape, raw_coordinates: sewn_sequence, recombined: true)
|
|
61
|
+
!(polyline.tile.tg_border?(position.payload) && position.end_point.tracked_outer)
|
|
96
62
|
end
|
|
97
63
|
end
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
missing_outer_polyline.turn_on(Polyline::TRACKED_INNER)
|
|
102
|
-
@orphan_inners += missing_shape.inner_polylines
|
|
64
|
+
if retme_sequence.is_not_vertical
|
|
65
|
+
return_inner_polylines << InnerPolyline.new(sequence: retme_sequence)
|
|
66
|
+
end
|
|
103
67
|
end
|
|
104
68
|
end
|
|
105
69
|
end
|
|
106
|
-
|
|
107
|
-
delay_shapes
|
|
70
|
+
return_inner_polylines
|
|
108
71
|
end
|
|
109
72
|
|
|
73
|
+
private
|
|
74
|
+
|
|
110
75
|
# rubocop:disable Lint/NonLocalExitFromIterator
|
|
111
76
|
def traverse_outer(act_part, all_parts, shapes_sequence, outer_joined_polyline)
|
|
112
77
|
last_part = all_parts.last
|
|
@@ -126,13 +91,19 @@ module Contrek
|
|
|
126
91
|
outer_joined_polyline.head.payload == new_position.payload &&
|
|
127
92
|
act_part == all_parts.first
|
|
128
93
|
outer_joined_polyline.add(Position.new(position: new_position.payload, hub: @cluster.hub))
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
94
|
+
new_position.end_point.tracked_outer = true
|
|
95
|
+
versus = act_part.versus
|
|
96
|
+
part = new_position.end_point.queues.find do |p|
|
|
97
|
+
p.versus == -versus && p.polyline.tile != act_part.polyline.tile
|
|
98
|
+
end
|
|
99
|
+
if part
|
|
100
|
+
if all_parts[-2] != part
|
|
101
|
+
cont = true
|
|
102
|
+
if all_parts.size >= 2
|
|
103
|
+
map = all_parts[-2..].map(&:type).uniq
|
|
104
|
+
cont = false if map.size == 1 && map.first == Part::SEAM
|
|
105
|
+
end
|
|
106
|
+
if cont
|
|
136
107
|
shapes_sequence.add(part.polyline.shape)
|
|
137
108
|
part.next_position(new_position)
|
|
138
109
|
part.dead_end = true
|
|
@@ -149,36 +120,9 @@ module Contrek
|
|
|
149
120
|
traverse_outer(act_part.circular_next, all_parts, shapes_sequence, outer_joined_polyline)
|
|
150
121
|
end
|
|
151
122
|
|
|
152
|
-
def collect_inner_sequences(outer_seq)
|
|
153
|
-
return_inner_polylines = []
|
|
154
|
-
@shapes_sequence.each do |shape|
|
|
155
|
-
polyline = shape.outer_polyline
|
|
156
|
-
polyline.parts.each do |part|
|
|
157
|
-
if part.innerable?
|
|
158
|
-
all_parts = []
|
|
159
|
-
bounds = {min: polyline.max_y, max: 0}
|
|
160
|
-
traverse_inner(part, all_parts, bounds)
|
|
161
|
-
range_of_bounds = (bounds[:min]..bounds[:max])
|
|
162
|
-
|
|
163
|
-
retme_sequence = Sequence.new
|
|
164
|
-
all_parts.each do |part|
|
|
165
|
-
part.touch!
|
|
166
|
-
retme_sequence.move_from(part) do |position|
|
|
167
|
-
next false if part.is?(Part::ADDED) && !(range_of_bounds === position.payload[:y])
|
|
168
|
-
!(polyline.tile.tg_border?(position.payload) && position.end_point.queues.include?(outer_seq))
|
|
169
|
-
end
|
|
170
|
-
end
|
|
171
|
-
if retme_sequence.is_not_vertical
|
|
172
|
-
return_inner_polylines << InnerPolyline.new(sequence: retme_sequence)
|
|
173
|
-
end
|
|
174
|
-
end
|
|
175
|
-
end
|
|
176
|
-
end
|
|
177
|
-
return_inner_polylines
|
|
178
|
-
end
|
|
179
|
-
|
|
180
123
|
def traverse_inner(act_part, all_parts, bounds)
|
|
181
124
|
return if act_part == all_parts.first
|
|
125
|
+
|
|
182
126
|
if act_part.size > 0
|
|
183
127
|
min_y, max_y = act_part.to_a.minmax_by { |p| p[:y] }
|
|
184
128
|
bounds[:min] = [bounds[:min], min_y[:y]].min
|
|
@@ -186,26 +130,32 @@ module Contrek
|
|
|
186
130
|
end
|
|
187
131
|
if act_part.innerable?
|
|
188
132
|
all_parts << act_part
|
|
189
|
-
while (act_part = act_part.
|
|
133
|
+
while (act_part = act_part.circular_next)
|
|
190
134
|
if act_part.innerable?
|
|
191
135
|
all_parts << act_part
|
|
192
136
|
else
|
|
193
|
-
act_part.
|
|
194
|
-
|
|
195
|
-
|
|
137
|
+
if act_part.head
|
|
138
|
+
eligibles = act_part.head.end_point.queues.select { |p| p.polyline.tile != act_part.polyline.tile }
|
|
139
|
+
eligibles.each do |dest_part|
|
|
196
140
|
dest_part_versus = dest_part.versus
|
|
197
141
|
next if dest_part_versus != 0 && dest_part_versus == act_part.versus
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
end
|
|
205
|
-
all_parts << ins_part
|
|
142
|
+
|
|
143
|
+
link_seq = dest_part.continuum_to?(act_part)
|
|
144
|
+
if link_seq.any?
|
|
145
|
+
ins_part = Part.new(Part::ADDED, act_part.polyline)
|
|
146
|
+
link_seq.each do |pos|
|
|
147
|
+
ins_part.add(Position.new(position: nil, hub: nil, known_endpoint: pos))
|
|
206
148
|
end
|
|
207
|
-
|
|
208
|
-
|
|
149
|
+
all_parts << ins_part
|
|
150
|
+
end
|
|
151
|
+
shape = dest_part.polyline.shape
|
|
152
|
+
if !dest_part.polyline.on?(Polyline::TRACKED_OUTER)
|
|
153
|
+
@processing_shapes << shape
|
|
154
|
+
@orphan_inners += shape.inner_polylines
|
|
155
|
+
end
|
|
156
|
+
dest_part.polyline.turn_on(Polyline::TRACKED_OUTER)
|
|
157
|
+
if !dest_part.touched
|
|
158
|
+
dest_part.touch!
|
|
209
159
|
traverse_inner(dest_part.circular_next, all_parts, bounds)
|
|
210
160
|
return
|
|
211
161
|
end
|
|
@@ -219,20 +169,6 @@ module Contrek
|
|
|
219
169
|
end
|
|
220
170
|
end
|
|
221
171
|
# rubocop:enable Lint/NonLocalExitFromIterator
|
|
222
|
-
|
|
223
|
-
# example
|
|
224
|
-
# a = [[A],[B,C]]
|
|
225
|
-
# b = [[D],[E,F]]
|
|
226
|
-
# res = [[D,B,C],[E,F,A]]
|
|
227
|
-
def combine!(seqa, seqb)
|
|
228
|
-
rets = []
|
|
229
|
-
[seqa.count, seqb.count].min.times do
|
|
230
|
-
last = seqa.pop
|
|
231
|
-
first = seqb.shift
|
|
232
|
-
rets << first + last
|
|
233
|
-
end
|
|
234
|
-
rets
|
|
235
|
-
end
|
|
236
172
|
end
|
|
237
173
|
end
|
|
238
174
|
end
|
|
@@ -7,8 +7,8 @@ module Contrek
|
|
|
7
7
|
EXCLUSIVE = 0
|
|
8
8
|
ADDED = 2
|
|
9
9
|
|
|
10
|
-
attr_reader :polyline, :
|
|
11
|
-
attr_accessor :next, :circular_next, :prev, :type, :dead_end, :inverts, :trasmuted, :
|
|
10
|
+
attr_reader :polyline, :touched
|
|
11
|
+
attr_accessor :next, :circular_next, :prev, :type, :dead_end, :inverts, :trasmuted, :versus
|
|
12
12
|
def initialize(type, polyline)
|
|
13
13
|
@type = type
|
|
14
14
|
@polyline = polyline
|
|
@@ -19,7 +19,6 @@ module Contrek
|
|
|
19
19
|
@touched = false
|
|
20
20
|
@inverts = false
|
|
21
21
|
@trasmuted = false
|
|
22
|
-
@delayed = false
|
|
23
22
|
@versus = 0
|
|
24
23
|
end
|
|
25
24
|
|
|
@@ -27,10 +26,6 @@ module Contrek
|
|
|
27
26
|
@type == type
|
|
28
27
|
end
|
|
29
28
|
|
|
30
|
-
def set_polyline(polyline)
|
|
31
|
-
@polyline = polyline
|
|
32
|
-
end
|
|
33
|
-
|
|
34
29
|
def add_position(position)
|
|
35
30
|
hub = is?(EXCLUSIVE) ? nil : polyline.tile.cluster.hub
|
|
36
31
|
add(Position.new(position: position, hub: hub))
|
|
@@ -68,19 +63,6 @@ module Contrek
|
|
|
68
63
|
(@touched == false) && is?(EXCLUSIVE)
|
|
69
64
|
end
|
|
70
65
|
|
|
71
|
-
def intersect_part?(other_part)
|
|
72
|
-
intersect = false
|
|
73
|
-
other_part.each do |position|
|
|
74
|
-
if position.end_point.queues.include?(self)
|
|
75
|
-
intersect = true
|
|
76
|
-
false
|
|
77
|
-
else
|
|
78
|
-
true
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
intersect
|
|
82
|
-
end
|
|
83
|
-
|
|
84
66
|
def orient!
|
|
85
67
|
@versus = if size <= 1 || (size == 2 && @inverts)
|
|
86
68
|
0
|
|
@@ -18,23 +18,6 @@ module Contrek
|
|
|
18
18
|
new_part.orient! if new_part.is?(Part::SEAM)
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
def insert_after(part, new_part)
|
|
22
|
-
part_index = @parts.index(part)
|
|
23
|
-
@parts.insert(part_index + 1, new_part)
|
|
24
|
-
new_part.prev = part
|
|
25
|
-
new_part.next = new_part.circular_next = part.next
|
|
26
|
-
part.next.prev = new_part if part.next
|
|
27
|
-
part.next = part.circular_next = new_part
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def find_first_part_by_position(position, versus)
|
|
31
|
-
@parts.find do |part|
|
|
32
|
-
part.is?(Part::SEAM) &&
|
|
33
|
-
part.versus == -versus &&
|
|
34
|
-
position.end_point.queues.include?(part)
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
21
|
def inspect_parts
|
|
39
22
|
[" "] + ["#{self.class} parts=#{@parts.size}"] + @parts.map { |p| p.inspect } + [" "]
|
|
40
23
|
end
|
|
@@ -67,70 +50,6 @@ module Contrek
|
|
|
67
50
|
trasmute_parts!
|
|
68
51
|
end
|
|
69
52
|
|
|
70
|
-
def sew!(intersection, other)
|
|
71
|
-
matching_part_indexes, other_matching_part_indexes = intersection.transpose.map(&:sort)
|
|
72
|
-
# other_matching_part_indexes and matching_part_indexes always must contain at least one element
|
|
73
|
-
before_parts = other.parts[other_matching_part_indexes.last + 1..]
|
|
74
|
-
after_parts = other_matching_part_indexes.first.zero? ? [] : other.parts[0..other_matching_part_indexes.first - 1]
|
|
75
|
-
part_start = parts[matching_part_indexes.first]
|
|
76
|
-
part_end = parts[matching_part_indexes.last]
|
|
77
|
-
|
|
78
|
-
# left and right side reduces will be combined and later converted into orphan inners sequences
|
|
79
|
-
returning_data = [[matching_part_indexes, parts], [other_matching_part_indexes, other.parts]].map do |matching_part_indexes, parts|
|
|
80
|
-
lastn = 0
|
|
81
|
-
result = []
|
|
82
|
-
(matching_part_indexes.first + 1).upto(matching_part_indexes.last - 1) do |n|
|
|
83
|
-
if matching_part_indexes.index(n).nil?
|
|
84
|
-
part = parts[n]
|
|
85
|
-
if part.is?(Part::SEAM) && part.size > 0 && !part.delayed # fallback, delays the shape
|
|
86
|
-
part.delayed = true
|
|
87
|
-
return nil
|
|
88
|
-
end
|
|
89
|
-
if (lastn == (n - 1)) && result.any?
|
|
90
|
-
result.last.concat part.to_a
|
|
91
|
-
else
|
|
92
|
-
result << part.to_a
|
|
93
|
-
end
|
|
94
|
-
lastn = n
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
result
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
if part_start != part_end
|
|
101
|
-
(matching_part_indexes.last - 1).downto(matching_part_indexes.first + 1) do |n|
|
|
102
|
-
delete_part = parts[n]
|
|
103
|
-
delete_part.prev.next = delete_part.next if delete_part.prev
|
|
104
|
-
delete_part.next.prev = delete_part.prev if delete_part.next
|
|
105
|
-
parts.delete_at(n)
|
|
106
|
-
end
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
all_parts = before_parts + after_parts
|
|
110
|
-
will_be_last = all_parts.last
|
|
111
|
-
all_parts.reverse_each do |part|
|
|
112
|
-
insert_after(part_start, part)
|
|
113
|
-
other.parts.delete(part)
|
|
114
|
-
part.set_polyline(self)
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
part_start.type = Part::EXCLUSIVE
|
|
118
|
-
new_end_part = Part.new(Part::EXCLUSIVE, self)
|
|
119
|
-
new_end_part.add(part_end.tail)
|
|
120
|
-
part_start.singleton! # reduce part to its head only
|
|
121
|
-
|
|
122
|
-
if part_start != part_end
|
|
123
|
-
part_end.prev.next = part_end.next if part_end.prev
|
|
124
|
-
part_end.next.prev = part_end.prev if part_end.next
|
|
125
|
-
parts.delete(part_end)
|
|
126
|
-
end
|
|
127
|
-
insert_after(will_be_last, new_end_part)
|
|
128
|
-
|
|
129
|
-
reset_tracked_endpoints!
|
|
130
|
-
|
|
131
|
-
returning_data
|
|
132
|
-
end
|
|
133
|
-
|
|
134
53
|
private
|
|
135
54
|
|
|
136
55
|
# If there are SEAM parts and one is canceled out by another within the same polyline,
|
|
@@ -4,10 +4,9 @@ module Contrek
|
|
|
4
4
|
prepend Partitionable
|
|
5
5
|
|
|
6
6
|
TRACKED_OUTER = 1 << 0
|
|
7
|
-
TRACKED_INNER = 1 << 1
|
|
8
7
|
|
|
9
|
-
attr_reader :raw, :name, :min_y, :max_y
|
|
10
|
-
attr_accessor :shape, :tile, :
|
|
8
|
+
attr_reader :raw, :name, :min_y, :max_y
|
|
9
|
+
attr_accessor :shape, :tile, :any_ancients
|
|
11
10
|
|
|
12
11
|
def initialize(tile:, polygon:, shape: nil, bounds: nil)
|
|
13
12
|
@tile = tile
|
|
@@ -15,7 +14,7 @@ module Contrek
|
|
|
15
14
|
@raw = polygon
|
|
16
15
|
@shape = shape
|
|
17
16
|
@flags = 0
|
|
18
|
-
@
|
|
17
|
+
@any_ancients = false
|
|
19
18
|
|
|
20
19
|
if bounds.nil?
|
|
21
20
|
find_boundary
|
|
@@ -55,38 +54,6 @@ module Contrek
|
|
|
55
54
|
(@flags & flag) != 0
|
|
56
55
|
end
|
|
57
56
|
|
|
58
|
-
def reset_tracked_endpoints!
|
|
59
|
-
@tracked_endpoints = nil
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
# returns for every position of intersection an array composed by the indexes of parts (self,other) involved
|
|
63
|
-
# es [[1,3],[2,6],...]. The first time the sequence for self is computed is stored.
|
|
64
|
-
def intersection(other)
|
|
65
|
-
if @tracked_endpoints.nil?
|
|
66
|
-
@tracked_endpoints = {} # memoize found sequence
|
|
67
|
-
parts.each_with_index do |part, part_index|
|
|
68
|
-
next if !part.is?(Part::SEAM) && part.trasmuted
|
|
69
|
-
part.each do |pos|
|
|
70
|
-
next if pos.end_point.nil?
|
|
71
|
-
@tracked_endpoints[pos.end_point.object_id] = part_index
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
matching_parts = []
|
|
76
|
-
other.parts.each_with_index do |part, part_index|
|
|
77
|
-
next if !part.is?(Part::SEAM) && part.trasmuted
|
|
78
|
-
part.each do |pos|
|
|
79
|
-
if (self_index = @tracked_endpoints[pos.end_point.object_id])
|
|
80
|
-
matching_parts << [self_index, part_index]
|
|
81
|
-
false
|
|
82
|
-
else
|
|
83
|
-
true
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
matching_parts
|
|
88
|
-
end
|
|
89
|
-
|
|
90
57
|
def empty?
|
|
91
58
|
@raw.empty?
|
|
92
59
|
end
|
|
@@ -104,17 +71,6 @@ module Contrek
|
|
|
104
71
|
@max_x - @min_x
|
|
105
72
|
end
|
|
106
73
|
|
|
107
|
-
# Pre-detects, for the current polyline, adjacent ones in the neighboring tile
|
|
108
|
-
# that vertically intersect.
|
|
109
|
-
def precalc!
|
|
110
|
-
@next_tile_eligible_shapes = @tile
|
|
111
|
-
.circular_next.boundary_shapes
|
|
112
|
-
.select { |s|
|
|
113
|
-
!s.outer_polyline.on?(Polyline::TRACKED_OUTER) &&
|
|
114
|
-
vert_intersect?(s.outer_polyline)
|
|
115
|
-
}
|
|
116
|
-
end
|
|
117
|
-
|
|
118
74
|
def vert_intersect?(other)
|
|
119
75
|
!(@max_y < other.min_y || other.max_y < @min_y)
|
|
120
76
|
end
|
|
@@ -20,11 +20,17 @@ module Contrek
|
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def after_add(new_queue)
|
|
23
|
-
@end_point
|
|
23
|
+
if @end_point && new_queue.instance_of?(Contrek::Concurrent::Part)
|
|
24
|
+
@end_point.queues << new_queue if !@end_point.queues.include?(new_queue)
|
|
25
|
+
if @end_point.queues.size > 1
|
|
26
|
+
new_queue.polyline.any_ancients = true
|
|
27
|
+
@end_point.queues.first.polyline.any_ancients = true
|
|
28
|
+
end
|
|
29
|
+
end
|
|
24
30
|
end
|
|
25
31
|
|
|
26
32
|
def before_rem(old_queue)
|
|
27
|
-
@end_point&.queues&.delete(old_queue)
|
|
33
|
+
# @end_point&.queues&.delete(old_queue) if old_queue.class == Contrek::Concurrent::Part
|
|
28
34
|
end
|
|
29
35
|
|
|
30
36
|
def inspect
|
|
@@ -10,16 +10,6 @@ module Contrek
|
|
|
10
10
|
@size = 0
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
def singleton!
|
|
14
|
-
if @head&.next
|
|
15
|
-
@head.next.prev = nil
|
|
16
|
-
@head.next = nil
|
|
17
|
-
end
|
|
18
|
-
@tail = nil
|
|
19
|
-
@size = 1
|
|
20
|
-
@iterator = 0
|
|
21
|
-
end
|
|
22
|
-
|
|
23
13
|
def rem(node)
|
|
24
14
|
Raise "Not my node" if node.owner != self
|
|
25
15
|
|
|
@@ -55,30 +45,6 @@ module Contrek
|
|
|
55
45
|
node.after_add(self)
|
|
56
46
|
end
|
|
57
47
|
|
|
58
|
-
def replace!(queueable)
|
|
59
|
-
reset!
|
|
60
|
-
append(queueable)
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def append(queueable)
|
|
64
|
-
return if queueable.size.zero?
|
|
65
|
-
queueable.each do |node|
|
|
66
|
-
node.before_rem(queueable)
|
|
67
|
-
node.owner = self
|
|
68
|
-
end
|
|
69
|
-
if @tail
|
|
70
|
-
@tail.next = queueable.head
|
|
71
|
-
queueable.head.prev = @tail
|
|
72
|
-
else
|
|
73
|
-
@head = queueable.head
|
|
74
|
-
end
|
|
75
|
-
@tail = queueable.tail
|
|
76
|
-
@size += queueable.size
|
|
77
|
-
queueable.reset!
|
|
78
|
-
|
|
79
|
-
each { |node| node.after_add(self) }
|
|
80
|
-
end
|
|
81
|
-
|
|
82
48
|
def move_from(queueable, &block)
|
|
83
49
|
queueable.rewind!
|
|
84
50
|
while (node = queueable.iterator)
|
|
@@ -87,13 +53,6 @@ module Contrek
|
|
|
87
53
|
end
|
|
88
54
|
end
|
|
89
55
|
|
|
90
|
-
def reset!
|
|
91
|
-
@head = nil
|
|
92
|
-
@tail = nil
|
|
93
|
-
@size = 0
|
|
94
|
-
@iterator = 0
|
|
95
|
-
end
|
|
96
|
-
|
|
97
56
|
# from yield: false => stop, true => continue
|
|
98
57
|
def each(&block)
|
|
99
58
|
last = nil
|
|
@@ -31,10 +31,6 @@ module Contrek
|
|
|
31
31
|
assign_raw_polygons!(result[:polygons], result.metadata[:treemap])
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
-
def boundary_shapes
|
|
35
|
-
@bbs ||= shapes.select { |s| s.outer_polyline.boundary? }
|
|
36
|
-
end
|
|
37
|
-
|
|
38
34
|
def iterate
|
|
39
35
|
@shapes.each do |shape|
|
|
40
36
|
shape.outer_polyline.raw.each do |position|
|
|
@@ -28,13 +28,17 @@ module Contrek
|
|
|
28
28
|
def transpose(result)
|
|
29
29
|
result.metadata[:width], result.metadata[:height] = result.metadata[:height], result.metadata[:width]
|
|
30
30
|
result.polygons.each do |polygon|
|
|
31
|
-
|
|
32
|
-
polygon[:
|
|
33
|
-
|
|
31
|
+
invert_point = ->(p) { {x: p[:y], y: p[:x]} }
|
|
32
|
+
polygon[:outer] = polygon[:outer].map(&invert_point)
|
|
33
|
+
polygon[:inner] = polygon[:inner].map do |sequence|
|
|
34
|
+
sequence.map(&invert_point)
|
|
34
35
|
end
|
|
35
36
|
if polygon.key?(:bounds)
|
|
36
|
-
|
|
37
|
-
polygon[:bounds]
|
|
37
|
+
b = polygon[:bounds]
|
|
38
|
+
polygon[:bounds] = {
|
|
39
|
+
min_x: b[:min_y], min_y: b[:min_x],
|
|
40
|
+
max_x: b[:max_y], max_y: b[:max_x]
|
|
41
|
+
}
|
|
38
42
|
end
|
|
39
43
|
end
|
|
40
44
|
result
|
data/lib/contrek/version.rb
CHANGED
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.1
|
|
4
|
+
version: 1.2.1
|
|
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-
|
|
11
|
+
date: 2026-05-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rspec
|
|
@@ -135,7 +135,6 @@ files:
|
|
|
135
135
|
- CHANGELOG.md
|
|
136
136
|
- Gemfile
|
|
137
137
|
- Gemfile.lock
|
|
138
|
-
- LICENSE-MIT.md
|
|
139
138
|
- LICENSE.md
|
|
140
139
|
- README.md
|
|
141
140
|
- Rakefile
|
|
@@ -242,6 +241,7 @@ files:
|
|
|
242
241
|
- ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/VisvalingamReducer.h
|
|
243
242
|
- ext/cpp_polygon_finder/cpp_polygon_finder.cpp
|
|
244
243
|
- ext/cpp_polygon_finder/extconf.rb
|
|
244
|
+
- lib/LICENSE-MIT.md
|
|
245
245
|
- lib/contrek.rb
|
|
246
246
|
- lib/contrek/bitmaps/bitmap.rb
|
|
247
247
|
- lib/contrek/bitmaps/chunky_bitmap.rb
|
|
File without changes
|