contrek 1.1.8 → 1.1.9
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 +5 -1
- data/Gemfile.lock +1 -1
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Node.cpp +0 -2
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cursor.cpp +1 -28
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cursor.h +0 -1
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Part.cpp +38 -23
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Part.h +1 -2
- data/lib/contrek/finder/concurrent/cursor.rb +1 -13
- data/lib/contrek/finder/concurrent/part.rb +26 -12
- data/lib/contrek/finder/concurrent/queueable.rb +0 -17
- data/lib/contrek/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 87e8665985a5c9b3818f5f405609c8bf0f9d81dfaa197054e0801acdc60dc56c
|
|
4
|
+
data.tar.gz: 450c56eda5bd65ab936fcd52b37e3f8edbc2ec0ac852aa0cc4c052ee6d81ab7e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e4cc2ea0d61819436e922eacdcad551658deceac1b5a907cea03d306de65fa2f71b96018acf6fcc6f88163775cabf0ba9b8d6ded3e9067dfcf3cc3e70d3e3e6d
|
|
7
|
+
data.tar.gz: ca933647465baca8a294176a1fbbc336bf1956c8eebab2cf48dd45ac4e55ba55ea84b00d38cbdd9ee0cf012b332684b8902c5e98a8cbaaafbfc846b374a12801
|
data/CHANGELOG.md
CHANGED
|
@@ -18,7 +18,7 @@ All notable changes to this project will be documented in this file.
|
|
|
18
18
|
### Added
|
|
19
19
|
- Added C++ multithreading supports
|
|
20
20
|
- Optimized old just present C++ code
|
|
21
|
-
- Removed Png++ dependency in place of
|
|
21
|
+
- Removed Png++ dependency in place of libspng
|
|
22
22
|
|
|
23
23
|
## [1.0.7] - 2026-01-10
|
|
24
24
|
### Added
|
|
@@ -76,3 +76,7 @@ All notable changes to this project will be documented in this file.
|
|
|
76
76
|
## [1.1.8] - 2026-04-19
|
|
77
77
|
### Changed
|
|
78
78
|
- Treemap now available on multiprocessing side too.
|
|
79
|
+
|
|
80
|
+
## [1.1.9] - 2026-04-24
|
|
81
|
+
### Changed
|
|
82
|
+
- Improved the internal parts joining algorithm, which was imprecise in some circumstances.
|
data/Gemfile.lock
CHANGED
|
@@ -280,7 +280,7 @@ void Cursor::traverse_inner(Part* act_part, std::vector<Part*>& all_parts, Bound
|
|
|
280
280
|
int dest_part_versus = dest_part->versus();
|
|
281
281
|
if (dest_part_versus != 0 && dest_part_versus == act_part->versus()) continue;
|
|
282
282
|
if (dest_part->intersect_part(act_part)) {
|
|
283
|
-
std::vector<EndPoint*> link_seq =
|
|
283
|
+
std::vector<EndPoint*> link_seq = dest_part->continuum_to(*act_part);
|
|
284
284
|
if (!link_seq.empty()) {
|
|
285
285
|
Part* ins_part = pool.acquire(Part::ADDED, act_part->polyline());
|
|
286
286
|
for (EndPoint* pos : link_seq) {
|
|
@@ -314,33 +314,6 @@ void Cursor::traverse_inner(Part* act_part, std::vector<Part*>& all_parts, Bound
|
|
|
314
314
|
}
|
|
315
315
|
}
|
|
316
316
|
|
|
317
|
-
template <typename T>
|
|
318
|
-
std::vector<T*> difference_ptr(std::vector<T*>& a, std::vector<T*>& b)
|
|
319
|
-
{ std::vector<T*> result;
|
|
320
|
-
for (T* item : a) {
|
|
321
|
-
auto it = std::find_if(
|
|
322
|
-
b.begin(), b.end(),
|
|
323
|
-
[&](T* other) {
|
|
324
|
-
return other == item;
|
|
325
|
-
});
|
|
326
|
-
if (it == b.end()) {
|
|
327
|
-
result.push_back(item);
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
return result;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
std::vector<EndPoint*> Cursor::duplicates_intersection(Part& part_a, Part& part_b) {
|
|
334
|
-
auto a1 = part_a.to_endpoints();
|
|
335
|
-
auto b1 = part_b.to_endpoints();
|
|
336
|
-
if (part_a.inverts) a1 = Part::remove_adjacent_pairs(a1);
|
|
337
|
-
if (part_b.inverts) b1 = Part::remove_adjacent_pairs(b1);
|
|
338
|
-
std::vector<EndPoint*> result = difference_ptr(a1, b1);
|
|
339
|
-
std::vector<EndPoint*> temp = difference_ptr(b1, a1);
|
|
340
|
-
result.insert(result.end(), temp.begin(), temp.end());
|
|
341
|
-
return result;
|
|
342
|
-
}
|
|
343
|
-
|
|
344
317
|
std::vector<std::vector<Point*>> Cursor::combine(std::vector<std::vector<Point*>>& seqa, std::vector<std::vector<Point*>>& seqb)
|
|
345
318
|
{ std::vector<std::vector<Point*>> rets;
|
|
346
319
|
size_t n = std::min(seqa.size(), seqb.size());
|
|
@@ -37,7 +37,6 @@ class Cursor {
|
|
|
37
37
|
Sequence* outer_joined_polyline);
|
|
38
38
|
std::vector<InnerPolyline*> collect_inner_sequences(Sequence* outer_seq);
|
|
39
39
|
void traverse_inner(Part* act_part, std::vector<Part*> &all_parts, Bounds& bounds);
|
|
40
|
-
std::vector<EndPoint*> duplicates_intersection(Part& part_a, Part& part_b);
|
|
41
40
|
std::vector<std::vector<Point*>> combine(std::vector<std::vector<Point*>>& seqa, std::vector<std::vector<Point*>>& seqb);
|
|
42
41
|
std::vector<Shape*> connect_missings(std::vector<Shape*> shapes_sequence, std::vector<Shape*> missing_shapes);
|
|
43
42
|
};
|
|
@@ -74,29 +74,6 @@ bool Part::intersect_part(Part* other_part)
|
|
|
74
74
|
return(intersect);
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
std::vector<EndPoint*> Part::to_endpoints() {
|
|
78
|
-
std::vector<EndPoint*> out;
|
|
79
|
-
QNode<Point>* current = head;
|
|
80
|
-
while (current) {
|
|
81
|
-
out.push_back((static_cast<Position*>(current))->end_point());
|
|
82
|
-
current = current->next;
|
|
83
|
-
}
|
|
84
|
-
return out;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
std::vector<EndPoint*> Part::remove_adjacent_pairs(const std::vector<EndPoint*>& input = {}) {
|
|
88
|
-
std::vector<EndPoint*> result;
|
|
89
|
-
result.reserve(input.size());
|
|
90
|
-
for (EndPoint* current : input) {
|
|
91
|
-
if (!result.empty() && result.back() == current) {
|
|
92
|
-
result.pop_back();
|
|
93
|
-
} else {
|
|
94
|
-
result.push_back(current);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
return result;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
77
|
void Part::orient()
|
|
101
78
|
{ if (this->size <= 1 || (this->size == 2 && this->inverts)) {
|
|
102
79
|
this->versus_ = 0;
|
|
@@ -127,3 +104,41 @@ std::string Part::inspect() {
|
|
|
127
104
|
ss << ")";
|
|
128
105
|
return ss.str();
|
|
129
106
|
}
|
|
107
|
+
|
|
108
|
+
std::vector<EndPoint*> Part::continuum_to(const Part& other_part) const {
|
|
109
|
+
if (this->size <= 2 && this->inverts && other_part.size <= 2 && other_part.inverts) return {};
|
|
110
|
+
|
|
111
|
+
Point* target = other_part.head->payload;
|
|
112
|
+
QNode<Point>* cursor = this->tail;
|
|
113
|
+
|
|
114
|
+
while (cursor != nullptr) {
|
|
115
|
+
if (*cursor->payload == *target) {
|
|
116
|
+
QNode<Point>* s = cursor;
|
|
117
|
+
QNode<Point>* o = other_part.head;
|
|
118
|
+
bool match = true;
|
|
119
|
+
int count = 0;
|
|
120
|
+
|
|
121
|
+
while (s != nullptr && o != nullptr) {
|
|
122
|
+
if (!(*s->payload == *o->payload)) {
|
|
123
|
+
match = false;
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
s = s->next;
|
|
127
|
+
o = o->next;
|
|
128
|
+
count++;
|
|
129
|
+
}
|
|
130
|
+
if (match && s == nullptr) {
|
|
131
|
+
std::vector<EndPoint*> res;
|
|
132
|
+
res.reserve(count);
|
|
133
|
+
s = cursor;
|
|
134
|
+
for (int i = 0; i < count; ++i) {
|
|
135
|
+
res.push_back(static_cast<Position*>(s)->end_point());
|
|
136
|
+
s = s->next;
|
|
137
|
+
}
|
|
138
|
+
return res;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
cursor = cursor->prev;
|
|
142
|
+
}
|
|
143
|
+
return {};
|
|
144
|
+
}
|
|
@@ -47,10 +47,9 @@ class Part : public Queueable<Point> {
|
|
|
47
47
|
void touch();
|
|
48
48
|
bool intersect_part(Part* other_part);
|
|
49
49
|
void set_polyline(Polyline* polyline) { this->polyline_ = polyline; }
|
|
50
|
-
std::vector<EndPoint*> to_endpoints();
|
|
51
|
-
static std::vector<EndPoint*> remove_adjacent_pairs(const std::vector<EndPoint*>& input);
|
|
52
50
|
void orient();
|
|
53
51
|
std::string inspect();
|
|
52
|
+
std::vector<EndPoint*> continuum_to(const Part& other_part) const;
|
|
54
53
|
|
|
55
54
|
private:
|
|
56
55
|
int versus_ = 0;
|
|
@@ -195,9 +195,8 @@ module Contrek
|
|
|
195
195
|
next if dest_part.trasmuted || dest_part.is?(Part::EXCLUSIVE)
|
|
196
196
|
dest_part_versus = dest_part.versus
|
|
197
197
|
next if dest_part_versus != 0 && dest_part_versus == act_part.versus
|
|
198
|
-
|
|
199
198
|
if dest_part.intersect_part?(act_part)
|
|
200
|
-
link_seq =
|
|
199
|
+
link_seq = dest_part.continuum_to?(act_part)
|
|
201
200
|
if link_seq.any?
|
|
202
201
|
ins_part = Part.new(Part::ADDED, act_part.polyline)
|
|
203
202
|
link_seq.each do |pos|
|
|
@@ -221,17 +220,6 @@ module Contrek
|
|
|
221
220
|
end
|
|
222
221
|
# rubocop:enable Lint/NonLocalExitFromIterator
|
|
223
222
|
|
|
224
|
-
# The sequences should contain inverted parts, e.g., 4,5,6,6,5,4. These parts must be
|
|
225
|
-
# removed from the sequences, and the remaining elements are compared. Only the
|
|
226
|
-
# elements that appear once between the two sequences are kept. This represents
|
|
227
|
-
# a connection between parts inserted afterwards.
|
|
228
|
-
# TODO evaluate the adoption of remove_adjacent_pairs!
|
|
229
|
-
def duplicates_intersection(part_a, part_b)
|
|
230
|
-
a1 = part_a.inverts ? Part.remove_adjacent_pairs(part_a.to_endpoints) : part_a.to_endpoints
|
|
231
|
-
b1 = part_b.inverts ? Part.remove_adjacent_pairs(part_b.to_endpoints) : part_b.to_endpoints
|
|
232
|
-
(a1 - b1) + (b1 - a1)
|
|
233
|
-
end
|
|
234
|
-
|
|
235
223
|
# example
|
|
236
224
|
# a = [[A],[B,C]]
|
|
237
225
|
# b = [[D],[E,F]]
|
|
@@ -81,10 +81,6 @@ module Contrek
|
|
|
81
81
|
intersect
|
|
82
82
|
end
|
|
83
83
|
|
|
84
|
-
def to_endpoints
|
|
85
|
-
map(&:end_point)
|
|
86
|
-
end
|
|
87
|
-
|
|
88
84
|
def orient!
|
|
89
85
|
@versus = if size <= 1 || (size == 2 && @inverts)
|
|
90
86
|
0
|
|
@@ -93,16 +89,34 @@ module Contrek
|
|
|
93
89
|
end
|
|
94
90
|
end
|
|
95
91
|
|
|
96
|
-
def
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
92
|
+
def continuum_to?(other)
|
|
93
|
+
return [] if size <= 2 && inverts && other.size <= 2 && other.inverts
|
|
94
|
+
return [] if other.head.nil?
|
|
95
|
+
|
|
96
|
+
target = other.head.payload
|
|
97
|
+
cursor = tail
|
|
98
|
+
while cursor
|
|
99
|
+
if cursor.payload == target
|
|
100
|
+
s = cursor
|
|
101
|
+
o = other.head
|
|
102
|
+
match = true
|
|
103
|
+
nodes = []
|
|
104
|
+
while s && o
|
|
105
|
+
if s.payload != o.payload
|
|
106
|
+
match = false
|
|
107
|
+
break
|
|
108
|
+
end
|
|
109
|
+
nodes << s.end_point
|
|
110
|
+
s = s.next
|
|
111
|
+
o = o.next
|
|
112
|
+
end
|
|
113
|
+
if match && s.nil?
|
|
114
|
+
return nodes
|
|
115
|
+
end
|
|
103
116
|
end
|
|
117
|
+
cursor = cursor.prev
|
|
104
118
|
end
|
|
105
|
-
|
|
119
|
+
[]
|
|
106
120
|
end
|
|
107
121
|
end
|
|
108
122
|
end
|
|
@@ -152,23 +152,6 @@ module Contrek
|
|
|
152
152
|
def pop!
|
|
153
153
|
rem(@tail)
|
|
154
154
|
end
|
|
155
|
-
|
|
156
|
-
def remove_adjacent_pairs!
|
|
157
|
-
unless @tail.nil?
|
|
158
|
-
pointer = @tail
|
|
159
|
-
loop do
|
|
160
|
-
break if pointer == @head
|
|
161
|
-
if pointer.payload == pointer.prev&.payload
|
|
162
|
-
later = pointer.next
|
|
163
|
-
rem pointer.prev
|
|
164
|
-
rem pointer
|
|
165
|
-
pointer = later.nil? ? @tail : later
|
|
166
|
-
redo
|
|
167
|
-
end
|
|
168
|
-
break unless (pointer = pointer.prev)
|
|
169
|
-
end
|
|
170
|
-
end
|
|
171
|
-
end
|
|
172
155
|
end
|
|
173
156
|
end
|
|
174
157
|
end
|
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.1.9
|
|
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-04-
|
|
11
|
+
date: 2026-04-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rspec
|