contrek 1.0.4 → 1.0.6
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/.gitignore +4 -3
- data/CHANGELOG.md +21 -0
- data/Gemfile.lock +4 -4
- data/README.md +34 -30
- data/Rakefile +3 -0
- data/contrek.gemspec +7 -4
- data/ext/cpp_polygon_finder/PolygonFinder/Makefile +44 -0
- data/ext/cpp_polygon_finder/PolygonFinder/images/sample_10240x10240.png +0 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/Main.cpp +14 -5
- data/ext/cpp_polygon_finder/PolygonFinder/src/Tests.cpp +136 -15
- data/ext/cpp_polygon_finder/PolygonFinder/src/Tests.h +5 -4
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/CpuTimer.h +44 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/Bitmap.cpp +8 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/Bitmap.h +3 -4
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/FastPngBitmap.cpp +63 -573
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/FastPngBitmap.h +17 -18
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/RemoteFastPngBitmap.cpp +22 -5
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/RemoteFastPngBitmap.h +4 -8
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/spng.c +6980 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/spng.h +537 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/FinderUtils.cpp +101 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/FinderUtils.h +16 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/List.cpp +0 -3
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/List.h +4 -7
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Lists.cpp +13 -13
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Lists.h +5 -7
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Node.cpp +47 -41
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Node.h +15 -10
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/NodeCluster.cpp +181 -178
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/NodeCluster.h +19 -20
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Polygon.h +20 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/PolygonFinder.cpp +52 -137
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/PolygonFinder.h +85 -16
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/RectBounds.h +39 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/ClippedPolygonFinder.cpp +14 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/ClippedPolygonFinder.h +17 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cluster.cpp +117 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cluster.h +32 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cursor.cpp +344 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cursor.h +46 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/EndPoint.cpp +14 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/EndPoint.h +22 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/FakeCluster.cpp +13 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/FakeCluster.h +17 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Finder.cpp +138 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Finder.h +52 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Hub.cpp +23 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Hub.h +40 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Part.cpp +70 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Part.h +47 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/PartPool.cpp +24 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/PartPool.h +23 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Partitionable.cpp +182 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Partitionable.h +30 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Polyline.cpp +108 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Polyline.h +52 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Poolable.cpp +59 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Poolable.h +52 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Position.cpp +31 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Position.h +25 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Queue.h +36 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Queueable.h +230 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Sequence.cpp +35 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Sequence.h +20 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Shape.cpp +26 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Shape.h +23 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Tile.cpp +105 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Tile.h +56 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/Matcher.cpp +3 -3
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/Matcher.h +5 -8
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/RGBMatcher.h +3 -7
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/RGBNotMatcher.cpp +2 -2
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/RGBNotMatcher.h +4 -8
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/ValueNotMatcher.cpp +2 -2
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/ValueNotMatcher.h +3 -7
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/LinearReducer.cpp +23 -15
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/LinearReducer.h +6 -8
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/Reducer.cpp +2 -5
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/Reducer.h +4 -8
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/UniqReducer.cpp +9 -12
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/UniqReducer.h +3 -7
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/VisvalingamReducer.cpp +26 -27
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/VisvalingamReducer.h +76 -87
- data/ext/cpp_polygon_finder/cpp_polygon_finder.cpp +64 -32
- data/ext/cpp_polygon_finder/extconf.rb +14 -0
- data/lib/contrek/bitmaps/sample_generator.rb +56 -0
- data/lib/contrek/cpp/cpp_concurrent_finder.rb +9 -0
- data/lib/contrek/finder/bounds.rb +17 -0
- data/lib/contrek/finder/concurrent/cluster.rb +2 -2
- data/lib/contrek/finder/concurrent/cursor.rb +8 -8
- data/lib/contrek/finder/concurrent/finder.rb +10 -9
- data/lib/contrek/finder/concurrent/part.rb +2 -2
- data/lib/contrek/finder/concurrent/partitionable.rb +1 -1
- data/lib/contrek/finder/concurrent/polyline.rb +17 -15
- data/lib/contrek/finder/concurrent/sequence.rb +11 -0
- data/lib/contrek/finder/concurrent/tile.rb +3 -3
- data/lib/contrek/finder/node_cluster.rb +16 -8
- data/lib/contrek/finder/polygon_finder.rb +1 -4
- data/lib/contrek/version.rb +1 -1
- data/lib/contrek.rb +9 -1
- metadata +62 -15
- data/ext/cpp_polygon_finder/PolygonFinder/.cproject +0 -136
- data/ext/cpp_polygon_finder/PolygonFinder/.project +0 -27
- data/ext/cpp_polygon_finder/PolygonFinder/.settings/org.eclipse.ltk.core.refactoring.prefs +0 -2
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/PngBitmap.cpp +0 -48
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/PngBitmap.h +0 -32
|
@@ -6,116 +6,104 @@
|
|
|
6
6
|
* Copyright 2025 Emanuele Cesaroni
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
#include "NodeCluster.h"
|
|
10
|
-
#include "Node.h"
|
|
11
|
-
#include "../reducers/UniqReducer.h"
|
|
12
|
-
#include "../reducers/LinearReducer.h"
|
|
13
|
-
#include "../reducers/VisvalingamReducer.h"
|
|
14
9
|
#include <iostream>
|
|
15
10
|
#include <list>
|
|
16
11
|
#include <algorithm>
|
|
17
12
|
#include <map>
|
|
18
13
|
#include <string>
|
|
19
14
|
#include <vector>
|
|
15
|
+
#include <utility>
|
|
16
|
+
#include "NodeCluster.h"
|
|
17
|
+
#include "Node.h"
|
|
18
|
+
#include "RectBounds.h"
|
|
19
|
+
#include "../reducers/UniqReducer.h"
|
|
20
|
+
#include "../reducers/LinearReducer.h"
|
|
21
|
+
#include "../reducers/VisvalingamReducer.h"
|
|
20
22
|
|
|
21
|
-
NodeCluster::NodeCluster(int h, pf_Options *options) {
|
|
22
|
-
this->vert_nodes = new std::vector<Node*>[h];
|
|
23
|
+
NodeCluster::NodeCluster(int h, int w, pf_Options *options) {
|
|
23
24
|
versus_inverter[Node::O] = Node::A;
|
|
24
25
|
versus_inverter[Node::A] = Node::O;
|
|
25
26
|
this->options = options;
|
|
26
27
|
this->height = h;
|
|
28
|
+
this->width = w;
|
|
27
29
|
this->nodes = 0;
|
|
28
|
-
|
|
29
|
-
this->
|
|
30
|
-
|
|
30
|
+
|
|
31
|
+
this->vert_nodes.resize(h);
|
|
32
|
+
for (int i = 0; i < h; ++i) {
|
|
33
|
+
this->vert_nodes[i].reserve(w/2);
|
|
34
|
+
}
|
|
31
35
|
|
|
32
36
|
this->root_nodes = this->lists.add_list();
|
|
33
37
|
this->inner_plot = this->lists.add_list();
|
|
34
38
|
this->inner_new = this->lists.add_list();
|
|
39
|
+
|
|
40
|
+
this->points.reserve(w * h);
|
|
35
41
|
}
|
|
36
42
|
|
|
37
43
|
NodeCluster::~NodeCluster() {
|
|
38
44
|
}
|
|
39
45
|
|
|
40
|
-
void NodeCluster::compress_coords(pf_Options options) {
|
|
41
|
-
if (options.compress_linear || options.compress_uniq || options.compress_visvalingam)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
46
|
+
void NodeCluster::compress_coords(std::list<Polygon>& polygons, pf_Options options) {
|
|
47
|
+
if (!(options.compress_linear || options.compress_uniq || options.compress_visvalingam)) return;
|
|
48
|
+
|
|
49
|
+
auto compress_sequence = [&](std::vector<Point*>& points_vec) {
|
|
50
|
+
if (points_vec.empty()) return;
|
|
51
|
+
|
|
52
|
+
if (options.compress_uniq) {
|
|
53
|
+
UniqReducer uniq_reducer(points_vec);
|
|
54
|
+
uniq_reducer.reduce();
|
|
50
55
|
}
|
|
51
|
-
if (options.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
reducer.reduce();
|
|
55
|
-
}
|
|
56
|
+
if (options.compress_linear) {
|
|
57
|
+
LinearReducer linear_reducer(points_vec);
|
|
58
|
+
linear_reducer.reduce();
|
|
56
59
|
}
|
|
57
|
-
if (options.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
reducer.reduce();
|
|
61
|
-
}
|
|
60
|
+
if (options.compress_visvalingam) {
|
|
61
|
+
VisvalingamReducer vis_reducer(points_vec, options.compress_visvalingam_tolerance);
|
|
62
|
+
vis_reducer.reduce();
|
|
62
63
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
};
|
|
65
|
+
for (auto &poly : polygons) {
|
|
66
|
+
compress_sequence(poly.outer);
|
|
67
|
+
for (auto &inner_seq : poly.inner) {
|
|
68
|
+
compress_sequence(inner_seq);
|
|
68
69
|
}
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
72
|
|
|
72
|
-
|
|
73
73
|
void NodeCluster::build_tangs_sequence() {
|
|
74
|
-
for (
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
for (auto& line : vert_nodes) {
|
|
75
|
+
for (Node& node : line) {
|
|
76
|
+
node.precalc_tangs_sequences(this->points);
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
Node* NodeCluster::add_node(int min_x, int max_x, int y, char name) {
|
|
82
|
+
vert_nodes[y].emplace_back(min_x, max_x, y, name);
|
|
83
|
+
|
|
84
|
+
Node& node = vert_nodes[y].back();
|
|
85
|
+
node.data_pointer = this->lists.get_data_pointer();
|
|
86
|
+
node.abs_x_index = vert_nodes[y].size() - 1;
|
|
82
87
|
this->nodes++;
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
(up_node)->add_intersection(node);
|
|
100
|
-
}
|
|
101
|
-
if (++index == up_nodes_count) return;
|
|
102
|
-
do
|
|
103
|
-
{ up_node = (*up_nodes)[index];
|
|
104
|
-
if (up_node->min_x <= node->max_x)
|
|
105
|
-
{ node->add_intersection(up_node);
|
|
106
|
-
(up_node)->add_intersection(node);
|
|
107
|
-
}
|
|
108
|
-
else return;
|
|
109
|
-
}while (++index != up_nodes_count);
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
}while(++index != up_nodes_count);
|
|
88
|
+
|
|
89
|
+
root_nodes->push_back(&node);
|
|
90
|
+
|
|
91
|
+
if (y > 0) {
|
|
92
|
+
std::vector<Node>& up_nodes = vert_nodes[y - 1];
|
|
93
|
+
if (!up_nodes.empty()) {
|
|
94
|
+
auto it = std::lower_bound(up_nodes.begin(), up_nodes.end(), node.min_x,
|
|
95
|
+
[](const Node& a, int val) {
|
|
96
|
+
return a.max_x < val;
|
|
97
|
+
});
|
|
98
|
+
while (it != up_nodes.end()) {
|
|
99
|
+
if (it->min_x > node.max_x) break;
|
|
100
|
+
node.add_intersection(&(*it));
|
|
101
|
+
it->add_intersection(&node);
|
|
102
|
+
++it;
|
|
103
|
+
}
|
|
113
104
|
}
|
|
114
105
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
std::list<Point*>* NodeCluster::get_coords() {
|
|
118
|
-
return(this->sequence_coords);
|
|
106
|
+
return &node;
|
|
119
107
|
}
|
|
120
108
|
|
|
121
109
|
void NodeCluster::plot(int versus) {
|
|
@@ -124,48 +112,47 @@ void NodeCluster::plot(int versus) {
|
|
|
124
112
|
Node *next_node;
|
|
125
113
|
|
|
126
114
|
while (root_nodes->size() > 0)
|
|
127
|
-
{ Node *root_node = (
|
|
115
|
+
{ Node *root_node = reinterpret_cast<Node*>(root_nodes->shift());
|
|
128
116
|
root_node->outer_index = index_order;
|
|
129
|
-
this->plot_sequence
|
|
130
|
-
this->
|
|
131
|
-
|
|
132
|
-
plot_sequence->push_back(root_node);
|
|
117
|
+
this->plot_sequence.clear();
|
|
118
|
+
this->plot_sequence.push_back(root_node);
|
|
119
|
+
Polygon poly;
|
|
133
120
|
|
|
134
|
-
if ((root_node)->tangs_sequence
|
|
135
|
-
{ versus == Node::A ? next_node = root_node->tangs_sequence
|
|
121
|
+
if ((root_node)->tangs_sequence.size() > 0) // front() on empty list is undefined
|
|
122
|
+
{ versus == Node::A ? next_node = root_node->tangs_sequence.back().node : next_node = root_node->tangs_sequence.front().node;
|
|
136
123
|
if (next_node != nullptr)
|
|
137
|
-
{
|
|
124
|
+
{ Point* p = next_node->coords_entering_to(root_node, versus_inverter[versus], Node::OUTER);
|
|
125
|
+
poly.outer.push_back(p);
|
|
126
|
+
poly.bounds.expand(p->x, p->y);
|
|
138
127
|
}
|
|
139
128
|
if ((this->nodes > 0) && (next_node != nullptr))
|
|
140
|
-
{ plot_node(next_node, root_node, versus);
|
|
129
|
+
{ plot_node(poly.outer, next_node, root_node, versus, poly.bounds);
|
|
130
|
+
}
|
|
131
|
+
this->sequences.push_back(std::move(this->plot_sequence));
|
|
132
|
+
this->plot_sequence.clear();
|
|
133
|
+
|
|
134
|
+
if (poly.outer.size() > 2)
|
|
135
|
+
{ this->polygons.push_back(poly);
|
|
141
136
|
}
|
|
142
|
-
this->sequences->push_back(plot_sequence);
|
|
143
|
-
std::list<std::list<Point*>*> outer_container, inner_container;
|
|
144
|
-
outer_container.push_back(sequence_coords);
|
|
145
|
-
std::list<Point*> pl_inner;
|
|
146
|
-
std::map<std::string, std::list<std::list<Point*>*>> poly;
|
|
147
|
-
poly["outer"] = outer_container;
|
|
148
|
-
poly["inner"] = inner_container;
|
|
149
|
-
if (sequence_coords->size() > 2) this->polygons.push_back(poly);
|
|
150
137
|
|
|
151
138
|
int index_inner = 0;
|
|
152
139
|
while (inner_plot->size() > 0)
|
|
153
|
-
{ this->plot_sequence
|
|
154
|
-
|
|
140
|
+
{ this->plot_sequence.clear();
|
|
141
|
+
std::vector<Point*> inner_sequence;
|
|
155
142
|
std::list<Node*>::iterator first_i;
|
|
156
143
|
Node *first = nullptr;
|
|
157
144
|
|
|
158
145
|
Listable *act = inner_plot->first();
|
|
159
146
|
do
|
|
160
|
-
{ if (((
|
|
161
|
-
{ first = (
|
|
147
|
+
{ if ((reinterpret_cast<Node*>(act))->tangs_count <= 2)
|
|
148
|
+
{ first = reinterpret_cast<Node*>(act);
|
|
162
149
|
break;
|
|
163
150
|
}
|
|
164
151
|
}while((act = act->data_pointer[inner_plot->get_id()].next) != nullptr);
|
|
165
152
|
|
|
166
|
-
if (first == nullptr) first = (
|
|
153
|
+
if (first == nullptr) first = reinterpret_cast<Node*>(inner_plot->first());
|
|
167
154
|
|
|
168
|
-
plot_sequence
|
|
155
|
+
plot_sequence.push_back(first);
|
|
169
156
|
inner_plot->remove(first);
|
|
170
157
|
root_nodes->remove(first);
|
|
171
158
|
|
|
@@ -181,16 +168,16 @@ void NodeCluster::plot(int versus) {
|
|
|
181
168
|
}
|
|
182
169
|
|
|
183
170
|
if (next_node != nullptr)
|
|
184
|
-
{
|
|
185
|
-
plot_inner_node(next_node, inner_v, first, root_node);
|
|
171
|
+
{ inner_sequence.push_back(next_node->coords_entering_to(first, inner_v, Node::INNER));
|
|
172
|
+
plot_inner_node(inner_sequence, next_node, inner_v, first, root_node);
|
|
186
173
|
}
|
|
187
|
-
|
|
188
|
-
this->polygons.back()["inner"].push_back(sequence_coords);
|
|
174
|
+
this->polygons.back().inner.push_back(inner_sequence);
|
|
189
175
|
this->inner_plot->grab(this->inner_new);
|
|
190
176
|
index_inner++;
|
|
191
177
|
}
|
|
192
178
|
} else {
|
|
193
|
-
this->sequences
|
|
179
|
+
this->sequences.push_back(std::move(this->plot_sequence));
|
|
180
|
+
this->plot_sequence.clear();
|
|
194
181
|
}
|
|
195
182
|
// tree
|
|
196
183
|
if (this->options->treemap)
|
|
@@ -200,110 +187,126 @@ void NodeCluster::plot(int versus) {
|
|
|
200
187
|
}
|
|
201
188
|
}
|
|
202
189
|
|
|
203
|
-
int
|
|
190
|
+
std::pair<int, int> NodeCluster::test_in_hole_a(Node* node)
|
|
204
191
|
{ if (node->outer_index > 0)
|
|
205
192
|
{ int start_left = node->abs_x_index - 1;
|
|
206
|
-
do
|
|
207
|
-
|
|
193
|
+
do {
|
|
194
|
+
Node* prev = &this->vert_nodes[node->y][start_left];
|
|
208
195
|
int cindex = prev->outer_index;
|
|
209
|
-
|
|
196
|
+
|
|
197
|
+
if ((cindex < node->outer_index) && (prev->track & Node::IMAX))
|
|
210
198
|
{ unsigned int start_right = node->abs_x_index;
|
|
211
199
|
unsigned int line_size = this->vert_nodes[node->y].size();
|
|
212
200
|
while (++start_right != line_size)
|
|
213
|
-
{ Node
|
|
214
|
-
if (tnext->outer_index == cindex)
|
|
215
|
-
|
|
216
|
-
else
|
|
201
|
+
{ Node* tnext = &this->vert_nodes[node->y][start_right];
|
|
202
|
+
if (tnext->outer_index == cindex) {
|
|
203
|
+
if (tnext->track & Node::IMIN) return {cindex, prev->inner_index};
|
|
204
|
+
else return {-1, -1};
|
|
217
205
|
}
|
|
218
206
|
}
|
|
219
207
|
}
|
|
220
|
-
}while(--start_left >= 0);
|
|
208
|
+
} while (--start_left >= 0);
|
|
221
209
|
}
|
|
222
|
-
return
|
|
210
|
+
return {-1, -1};
|
|
223
211
|
}
|
|
224
212
|
|
|
225
|
-
int
|
|
226
|
-
{
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
213
|
+
std::pair<int, int> NodeCluster::test_in_hole_o(Node* node)
|
|
214
|
+
{ auto& line = this->vert_nodes[node->y];
|
|
215
|
+
const unsigned int line_size = line.size();
|
|
216
|
+
if (node->outer_index == 0 || &line.back() == node) return {-1, -1};
|
|
217
|
+
|
|
218
|
+
unsigned int start_left = node->abs_x_index + 1;
|
|
219
|
+
do {
|
|
220
|
+
Node* prev = &line[start_left];
|
|
221
|
+
int cindex = prev->outer_index;
|
|
222
|
+
|
|
223
|
+
if (cindex < node->outer_index && (prev->track & Node::IMIN))
|
|
224
|
+
{ int start_right = node->abs_x_index;
|
|
225
|
+
while (--start_right >= 0) {
|
|
226
|
+
Node* tnext = &line[start_right];
|
|
227
|
+
if (tnext->outer_index == cindex) {
|
|
228
|
+
if (tnext->track & Node::IMAX) return {cindex, prev->inner_index};
|
|
229
|
+
else return {-1, -1};
|
|
240
230
|
}
|
|
241
231
|
}
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
return
|
|
232
|
+
}
|
|
233
|
+
} while (++start_left != line_size);
|
|
234
|
+
return {-1, -1};
|
|
245
235
|
}
|
|
246
236
|
|
|
247
|
-
void NodeCluster::plot_inner_node(Node *node, int versus, Node *stop_at, Node *start_node) {
|
|
248
|
-
|
|
249
|
-
node->inner_index = stop_at->inner_index;
|
|
250
|
-
root_nodes->remove(node);
|
|
251
|
-
inner_plot->remove(node);
|
|
237
|
+
void NodeCluster::plot_inner_node(std::vector<Point*>& sequence_coords, Node *node, int versus, Node *stop_at, Node *start_node) {
|
|
238
|
+
Node *current_node = node;
|
|
252
239
|
|
|
253
|
-
|
|
254
|
-
|
|
240
|
+
while (current_node != nullptr) {
|
|
241
|
+
current_node->outer_index = start_node->outer_index;
|
|
242
|
+
current_node->inner_index = stop_at->inner_index;
|
|
243
|
+
root_nodes->remove(current_node);
|
|
244
|
+
inner_plot->remove(current_node);
|
|
255
245
|
|
|
256
|
-
|
|
246
|
+
Node *last_node = plot_sequence.back();
|
|
247
|
+
Node *next_node = current_node->my_next_inner(last_node, versus);
|
|
257
248
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
if (
|
|
266
|
-
|
|
267
|
-
|
|
249
|
+
plot_sequence.push_back(current_node);
|
|
250
|
+
|
|
251
|
+
bool plot = true;
|
|
252
|
+
if (next_node->y == last_node->y) {
|
|
253
|
+
Node *n = (versus == Node::A ? current_node->tangs_sequence.front().node : current_node->tangs_sequence.back().node);
|
|
254
|
+
plot = (n == next_node);
|
|
255
|
+
}
|
|
256
|
+
if (plot) {
|
|
257
|
+
sequence_coords.push_back(last_node->coords_entering_to(current_node, versus_inverter[versus], Node::INNER));
|
|
258
|
+
if (current_node != start_node) {
|
|
259
|
+
if (last_node->y == next_node->y) {
|
|
260
|
+
sequence_coords.push_back(next_node->coords_entering_to(current_node, versus, Node::INNER));
|
|
261
|
+
}
|
|
268
262
|
}
|
|
269
263
|
}
|
|
264
|
+
if (current_node->track_uncomplete()) {
|
|
265
|
+
this->inner_new->push_back(current_node);
|
|
266
|
+
} else {
|
|
267
|
+
inner_new->remove(current_node);
|
|
268
|
+
}
|
|
269
|
+
if (next_node == stop_at) break;
|
|
270
|
+
current_node = next_node;
|
|
270
271
|
}
|
|
271
|
-
if (node->track_uncomplete())
|
|
272
|
-
{ this->inner_new->push_back(node);
|
|
273
|
-
} else {
|
|
274
|
-
inner_new->remove(node);
|
|
275
|
-
}
|
|
276
|
-
if (next_node == stop_at) return;
|
|
277
|
-
plot_inner_node(next_node, versus, stop_at, start_node);
|
|
278
272
|
}
|
|
279
273
|
|
|
280
|
-
void NodeCluster::plot_node(Node *node, Node *start_node, int versus) {
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
plot_sequence->push_back(node);
|
|
287
|
-
bool plot = true;
|
|
288
|
-
if (next_node -> y == last_node -> y)
|
|
289
|
-
{ Node *n = (versus == Node::A ? node->tangs_sequence->back()->node : node->tangs_sequence->front()->node);
|
|
290
|
-
plot = (n == next_node);
|
|
291
|
-
}
|
|
274
|
+
void NodeCluster::plot_node(std::vector<Point*>& sequence_coords, Node *node, Node *start_node, int versus, RectBounds& bounds) {
|
|
275
|
+
Node *current_node = node;
|
|
276
|
+
|
|
277
|
+
while (current_node != nullptr) {
|
|
278
|
+
root_nodes->remove(current_node);
|
|
279
|
+
current_node->outer_index = start_node->outer_index;
|
|
292
280
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
281
|
+
Node *last_node = plot_sequence.back();
|
|
282
|
+
Node *next_node = current_node->my_next_outer(last_node, versus);
|
|
283
|
+
|
|
284
|
+
plot_sequence.push_back(current_node);
|
|
285
|
+
|
|
286
|
+
bool plot = true;
|
|
287
|
+
if (next_node->y == last_node->y) {
|
|
288
|
+
Node *n = (versus == Node::A ? current_node->tangs_sequence.back().node : current_node->tangs_sequence.front().node);
|
|
289
|
+
plot = (n == next_node);
|
|
290
|
+
}
|
|
291
|
+
if (plot) {
|
|
292
|
+
Point* p = last_node->coords_entering_to(current_node, versus, Node::OUTER);
|
|
293
|
+
sequence_coords.push_back(p);
|
|
294
|
+
bounds.expand(p->x, p->y);
|
|
295
|
+
if (current_node != start_node) {
|
|
296
|
+
inner_plot->contains(current_node) ? inner_plot->remove(current_node) : inner_plot->push_back(current_node);
|
|
297
|
+
if (last_node->y == next_node->y) {
|
|
298
|
+
Point* p1 = next_node->coords_entering_to(current_node, versus_inverter[versus], Node::OUTER);
|
|
299
|
+
sequence_coords.push_back(p1);
|
|
300
|
+
bounds.expand(p1->x, p1->y);
|
|
301
|
+
inner_plot->contains(current_node) ? inner_plot->remove(current_node) : inner_plot->push_back(current_node);
|
|
302
|
+
}
|
|
300
303
|
}
|
|
301
304
|
}
|
|
305
|
+
if (current_node == start_node) {
|
|
306
|
+
if (current_node->track_complete()) break;
|
|
307
|
+
}
|
|
308
|
+
current_node = next_node;
|
|
302
309
|
}
|
|
303
|
-
if (node == start_node)
|
|
304
|
-
{ if (node->track_complete()) return;
|
|
305
|
-
}
|
|
306
|
-
plot_node(next_node, start_node, versus);
|
|
307
310
|
}
|
|
308
311
|
|
|
309
312
|
void NodeCluster::list_track(Node *node, std::list<Node*> *list) {
|
|
@@ -6,14 +6,16 @@
|
|
|
6
6
|
* Copyright 2025 Emanuele Cesaroni
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
#
|
|
10
|
-
#define POLYGON_FINDER_NODECLUSTER_H_
|
|
9
|
+
#pragma once
|
|
11
10
|
#include <list>
|
|
12
11
|
#include <vector>
|
|
13
12
|
#include <map>
|
|
14
13
|
#include <string>
|
|
14
|
+
#include <utility>
|
|
15
15
|
#include "PolygonFinder.h"
|
|
16
16
|
#include "Lists.h"
|
|
17
|
+
#include "RectBounds.h"
|
|
18
|
+
#include "Polygon.h"
|
|
17
19
|
|
|
18
20
|
class Node;
|
|
19
21
|
struct Point;
|
|
@@ -21,39 +23,36 @@ struct pf_Options;
|
|
|
21
23
|
|
|
22
24
|
class NodeCluster {
|
|
23
25
|
private:
|
|
24
|
-
void plot_node(Node *node, Node *start_node, int versus);
|
|
25
|
-
void plot_inner_node(Node *node, int versus, Node *stop_at, Node *start_node);
|
|
26
|
-
std::
|
|
26
|
+
void plot_node(std::vector<Point*>& sequence_coords, Node *node, Node *start_node, int versus, RectBounds& bounds);
|
|
27
|
+
void plot_inner_node(std::vector<Point*>& sequence_coords, Node *node, int versus, Node *stop_at, Node *start_node);
|
|
28
|
+
std::vector<Node*> plot_sequence;
|
|
27
29
|
List *inner_plot;
|
|
28
|
-
std::list<Point*> *sequence_coords;
|
|
29
30
|
List *inner_new;
|
|
30
31
|
int versus_inverter[2];
|
|
31
32
|
int count = 0;
|
|
32
33
|
int nodes;
|
|
33
|
-
|
|
34
|
+
std::vector<Point> points;
|
|
34
35
|
|
|
35
36
|
public:
|
|
36
|
-
|
|
37
|
-
int
|
|
38
|
-
int
|
|
39
|
-
std::
|
|
37
|
+
pf_Options *options;
|
|
38
|
+
std::vector<std::pair<int, int>> treemap; // [a,b] a = index of parent outer, b = index of inner of parent outer
|
|
39
|
+
std::pair<int, int> test_in_hole_a(Node* node);
|
|
40
|
+
std::pair<int, int> test_in_hole_o(Node* node);
|
|
41
|
+
std::vector<std::vector<Node>> vert_nodes;
|
|
40
42
|
void list_track(Node *node, std::list<Node*> *list);
|
|
41
43
|
void list_delete(Node *node, std::list<Node*> *list);
|
|
42
44
|
bool list_present(Node *node, std::list<Node*> *list);
|
|
43
|
-
void compress_coords(pf_Options options);
|
|
45
|
+
void compress_coords(std::list<Polygon>& polygons, pf_Options options);
|
|
44
46
|
List *root_nodes;
|
|
45
|
-
int height;
|
|
46
|
-
std::list<
|
|
47
|
-
NodeCluster(int h, pf_Options *options);
|
|
47
|
+
int height, width;
|
|
48
|
+
std::list<Polygon> polygons;
|
|
49
|
+
NodeCluster(int h, int w, pf_Options *options);
|
|
48
50
|
virtual ~NodeCluster();
|
|
49
|
-
|
|
51
|
+
Node* add_node(int min_x, int max_x, int y, char name);
|
|
50
52
|
void calc_root_nodes();
|
|
51
53
|
void build_tangs_sequence();
|
|
52
54
|
void plot(int versus);
|
|
53
55
|
Lists lists;
|
|
54
56
|
std::list<Node*>::iterator exam(std::list<Node*>::iterator inode, Node *node, Node *father, Node *root_node);
|
|
55
|
-
std::
|
|
56
|
-
std::list<std::list<Node*>*> *sequences;
|
|
57
|
+
std::vector<std::vector<Node*>> sequences;
|
|
57
58
|
};
|
|
58
|
-
|
|
59
|
-
#endif /* POLYGON_FINDER_NODECLUSTER_H_ */
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Polygon.h
|
|
3
|
+
*
|
|
4
|
+
* Created on: 23 nov 2025
|
|
5
|
+
* Author: ema
|
|
6
|
+
* Copyright 2025 Emanuele Cesaroni
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#pragma once
|
|
10
|
+
#include <vector>
|
|
11
|
+
#include <list>
|
|
12
|
+
#include "Node.h"
|
|
13
|
+
#include "RectBounds.h"
|
|
14
|
+
|
|
15
|
+
struct Polygon {
|
|
16
|
+
std::vector<Point*> outer;
|
|
17
|
+
std::list<std::vector<Point*>> inner;
|
|
18
|
+
RectBounds bounds;
|
|
19
|
+
Polygon() : bounds(RectBounds::empty()) {}
|
|
20
|
+
};
|