contrek 1.2.9 → 1.3.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 +7 -0
- data/Gemfile.lock +1 -1
- data/ext/cpp_polygon_finder/PolygonFinder/src/Tests.cpp +13 -27
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Node.cpp +5 -7
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Node.h +4 -1
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/NodeCluster.cpp +14 -15
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/NodeCluster.h +2 -4
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Polygon.h +2 -2
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/PolygonFinder.cpp +13 -12
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/PolygonFinder.h +10 -58
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cluster.cpp +6 -6
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cluster.h +3 -2
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cursor.cpp +8 -13
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/EndPoint.h +4 -4
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Finder.h +2 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/InnerPolyline.cpp +6 -6
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/InnerPolyline.h +3 -3
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Merger.cpp +4 -3
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Part.cpp +59 -9
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Part.h +6 -1
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Partitionable.cpp +48 -33
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Partitionable.h +4 -2
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Polyline.cpp +13 -13
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Polyline.h +4 -4
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Position.cpp +2 -2
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Position.h +1 -1
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Queueable.h +4 -4
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Sequence.cpp +7 -7
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Sequence.h +2 -2
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Shape.cpp +8 -2
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Shape.h +4 -1
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/ShapePool.cpp +20 -5
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/ShapePool.h +6 -2
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/StreamingMerger.cpp +8 -5
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Tile.cpp +9 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Tile.h +1 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/VerticalMerger.cpp +4 -13
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/VerticalMerger.h +1 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/LinearReducer.cpp +8 -8
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/LinearReducer.h +2 -2
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/Reducer.cpp +1 -1
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/Reducer.h +2 -2
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/UniqReducer.cpp +3 -3
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/UniqReducer.h +1 -1
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/VisvalingamReducer.cpp +3 -3
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/VisvalingamReducer.h +10 -10
- data/ext/cpp_polygon_finder/cpp_polygon_finder.cpp +14 -14
- data/lib/contrek/bitmaps/chunky_bitmap.rb +11 -0
- data/lib/contrek/finder/concurrent/cluster.rb +1 -1
- data/lib/contrek/finder/concurrent/cursor.rb +0 -3
- data/lib/contrek/finder/concurrent/finder.rb +4 -0
- data/lib/contrek/finder/concurrent/merger.rb +1 -0
- data/lib/contrek/finder/concurrent/part.rb +36 -1
- data/lib/contrek/finder/concurrent/partitionable.rb +42 -23
- data/lib/contrek/finder/concurrent/vertical_merger.rb +4 -0
- data/lib/contrek/finder/polygon_finder.rb +2 -1
- data/lib/contrek/version.rb +1 -1
- metadata +5 -5
|
@@ -32,6 +32,7 @@ void StreamingMerger::add_tile(ProcessResult& result, bool flush)
|
|
|
32
32
|
this->process_tiles();
|
|
33
33
|
this->tiles_.queue_push(this->whole_tile);
|
|
34
34
|
this->stream_polygons(this->whole_tile, flush);
|
|
35
|
+
this->whole_tile->shapes().shrink_to_fit();
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
38
|
|
|
@@ -45,16 +46,18 @@ void StreamingMerger::stream_polygons(Tile* tile, bool flush) {
|
|
|
45
46
|
ensure_header();
|
|
46
47
|
if (int tile_end_x = tile->end_x(); true) {
|
|
47
48
|
tile->shapes().erase(
|
|
48
|
-
std::remove_if(tile->shapes().begin(), tile->shapes().end(), [this, flush, tile_end_x](
|
|
49
|
+
std::remove_if(tile->shapes().begin(), tile->shapes().end(), [this, flush, tile_end_x](Shape* shape) {
|
|
49
50
|
if (flush || shape->outer_polyline->max_x() < (tile_end_x - 1)) {
|
|
50
51
|
this->moved++;
|
|
51
52
|
this->stream_raw_polygon(shape);
|
|
53
|
+
shape->detach_from_pool();
|
|
52
54
|
return true;
|
|
53
55
|
}
|
|
54
56
|
return false;
|
|
55
57
|
}),
|
|
56
58
|
tile->shapes().end());
|
|
57
59
|
}
|
|
60
|
+
stream->flush();
|
|
58
61
|
if (flush) {
|
|
59
62
|
ensure_footer();
|
|
60
63
|
}
|
|
@@ -62,18 +65,18 @@ void StreamingMerger::stream_polygons(Tile* tile, bool flush) {
|
|
|
62
65
|
|
|
63
66
|
void StreamingMerger::stream_raw_polygon(const Shape* shape) {
|
|
64
67
|
std::ostringstream outer_oss;
|
|
65
|
-
const std::vector<Point
|
|
68
|
+
const std::vector<Point>& points = shape->outer_polyline->raw();
|
|
66
69
|
for (size_t i = 0; i < points.size(); ++i) {
|
|
67
|
-
outer_oss << points[i]
|
|
70
|
+
outer_oss << points[i].y << "," << points[i].x;
|
|
68
71
|
if (i < points.size() - 1) outer_oss << " ";
|
|
69
72
|
}
|
|
70
73
|
*stream << svg_outer_polygon_string(outer_oss.str());
|
|
71
74
|
|
|
72
75
|
for (const auto& inner_polyline : shape->inner_polylines) {
|
|
73
76
|
std::ostringstream inner_oss;
|
|
74
|
-
const std::vector<Point
|
|
77
|
+
const std::vector<Point>& inner_points = inner_polyline->raw();
|
|
75
78
|
for (size_t i = 0; i < inner_points.size(); ++i) {
|
|
76
|
-
inner_oss << inner_points[i]
|
|
79
|
+
inner_oss << inner_points[i].y << "," << inner_points[i].x;
|
|
77
80
|
if (i < inner_points.size() - 1) inner_oss << " ";
|
|
78
81
|
}
|
|
79
82
|
*stream << svg_inner_polygon_string(inner_oss.str());
|
|
@@ -27,6 +27,7 @@ Tile::Tile(Finder *finder, int start_x, int end_x, std::string name, const Bench
|
|
|
27
27
|
name_(name),
|
|
28
28
|
benchmarks(b) {
|
|
29
29
|
this->shapes_pool = new ShapePool();
|
|
30
|
+
this->shapes_pool->set_owner(this);
|
|
30
31
|
this->shapes_pools.push_back(this->shapes_pool);
|
|
31
32
|
}
|
|
32
33
|
|
|
@@ -156,6 +157,14 @@ std::vector<std::pair<int, int>> Tile::compute_treemap()
|
|
|
156
157
|
void Tile::adopt(Tile* other) {
|
|
157
158
|
for (ShapePool* pool : other->shapes_pools) {
|
|
158
159
|
this->shapes_pools.push_back(pool);
|
|
160
|
+
pool->set_owner(this);
|
|
159
161
|
}
|
|
160
162
|
other->shapes_pools.clear();
|
|
161
163
|
}
|
|
164
|
+
|
|
165
|
+
void Tile::unregister_pool(ShapePool* shape_pool) {
|
|
166
|
+
auto it = std::find(this->shapes_pools.begin(), this->shapes_pools.end(), shape_pool);
|
|
167
|
+
if (it != this->shapes_pools.end()) {
|
|
168
|
+
this->shapes_pools.erase(it);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
#include <vector>
|
|
13
13
|
#include <algorithm>
|
|
14
14
|
#include <utility>
|
|
15
|
-
#include <unordered_set>
|
|
16
15
|
#include "VerticalMerger.h"
|
|
17
16
|
|
|
18
17
|
VerticalMerger::VerticalMerger(int number_of_threads, std::vector<std::string> *options)
|
|
@@ -36,21 +35,13 @@ ProcessResult* VerticalMerger::process_info() {
|
|
|
36
35
|
|
|
37
36
|
void VerticalMerger::transpose(ProcessResult& result) {
|
|
38
37
|
std::swap(result.width, result.height);
|
|
39
|
-
std::unordered_set<Point*> seen;
|
|
40
38
|
for (auto& polygon : result.polygons) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (seen.insert(p).second) {
|
|
44
|
-
std::swap(p->x, p->y);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
for (Point* p : polygon.outer) {
|
|
49
|
-
process_p(p);
|
|
39
|
+
for (Point& p : polygon.outer) {
|
|
40
|
+
std::swap(p.x, p.y);
|
|
50
41
|
}
|
|
51
42
|
for (auto& sequence : polygon.inner) {
|
|
52
|
-
for (Point
|
|
53
|
-
|
|
43
|
+
for (Point& p : sequence) {
|
|
44
|
+
std::swap(p.x, p.y);
|
|
54
45
|
}
|
|
55
46
|
}
|
|
56
47
|
std::swap(polygon.bounds.min_x, polygon.bounds.min_y);
|
|
@@ -17,6 +17,7 @@ class VerticalMerger : public Merger {
|
|
|
17
17
|
VerticalMerger(int number_of_threads, std::vector<std::string> *options);
|
|
18
18
|
void add_tile(ProcessResult& result) override;
|
|
19
19
|
ProcessResult* process_info() override;
|
|
20
|
+
bool transpose() const override { return true; };
|
|
20
21
|
|
|
21
22
|
private:
|
|
22
23
|
void transpose(ProcessResult& result);
|
|
@@ -14,23 +14,23 @@
|
|
|
14
14
|
#include "LinearReducer.h"
|
|
15
15
|
#include "Reducer.h"
|
|
16
16
|
|
|
17
|
-
LinearReducer::LinearReducer(std::vector<Point
|
|
17
|
+
LinearReducer::LinearReducer(std::vector<Point>& list_of_points)
|
|
18
18
|
: Reducer(list_of_points) {
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
void LinearReducer::reduce() {
|
|
22
22
|
if (points.size() < 2) return;
|
|
23
23
|
|
|
24
|
-
Point
|
|
25
|
-
Point
|
|
24
|
+
Point start_p = points[0];
|
|
25
|
+
Point end_p = points[1];
|
|
26
26
|
auto dir = seq_dir(start_p, end_p);
|
|
27
27
|
|
|
28
28
|
for (size_t i = 2; i < points.size(); ++i) {
|
|
29
|
-
Point
|
|
29
|
+
Point point = points[i];
|
|
30
30
|
auto act_seq = seq_dir(end_p, point);
|
|
31
31
|
if (act_seq == dir) {
|
|
32
|
-
auto it = std::find_if(points.begin(), points.end(), [&](Point
|
|
33
|
-
return p
|
|
32
|
+
auto it = std::find_if(points.begin(), points.end(), [&](const Point& p) { // TODO(ema): optimize...
|
|
33
|
+
return p.x == end_p.x && p.y == end_p.y;
|
|
34
34
|
});
|
|
35
35
|
if (it != points.end()) {
|
|
36
36
|
size_t removed_idx = std::distance(points.begin(), it);
|
|
@@ -44,6 +44,6 @@ void LinearReducer::reduce() {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
std::array<int, 2> LinearReducer::seq_dir(Point
|
|
48
|
-
{ return { b
|
|
47
|
+
std::array<int, 2> LinearReducer::seq_dir(const Point& a, const Point& b)
|
|
48
|
+
{ return { b.x - a.x, b.y - a.y };
|
|
49
49
|
}
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
|
|
15
15
|
class LinearReducer : public Reducer {
|
|
16
16
|
public:
|
|
17
|
-
explicit LinearReducer(std::vector<Point
|
|
17
|
+
explicit LinearReducer(std::vector<Point>& list_of_points);
|
|
18
18
|
void reduce();
|
|
19
19
|
|
|
20
20
|
private:
|
|
21
|
-
std::array<int, 2> seq_dir(Point
|
|
21
|
+
std::array<int, 2> seq_dir(const Point& a, const Point& b);
|
|
22
22
|
};
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
struct Point;
|
|
16
16
|
class Reducer {
|
|
17
17
|
public:
|
|
18
|
-
explicit Reducer(std::vector<Point
|
|
18
|
+
explicit Reducer(std::vector<Point>& list_of_points);
|
|
19
19
|
virtual void reduce();
|
|
20
20
|
protected:
|
|
21
|
-
std::vector<Point
|
|
21
|
+
std::vector<Point> &points;
|
|
22
22
|
};
|
|
@@ -13,12 +13,12 @@
|
|
|
13
13
|
#include "UniqReducer.h"
|
|
14
14
|
#include "Reducer.h"
|
|
15
15
|
|
|
16
|
-
UniqReducer::UniqReducer(std::vector<Point
|
|
16
|
+
UniqReducer::UniqReducer(std::vector<Point>& list_of_points) : Reducer(list_of_points) {
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
struct is_near {
|
|
20
|
-
bool operator() (Point
|
|
21
|
-
return first
|
|
20
|
+
bool operator() (const Point& first, const Point& second) const {
|
|
21
|
+
return first.x == second.x && first.y == second.y;
|
|
22
22
|
}
|
|
23
23
|
};
|
|
24
24
|
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
#include <vector>
|
|
11
11
|
#include "VisvalingamReducer.h"
|
|
12
12
|
|
|
13
|
-
VisvalingamReducer::VisvalingamReducer(std::vector<Point
|
|
13
|
+
VisvalingamReducer::VisvalingamReducer(std::vector<Point>& list_of_points, float tolerance)
|
|
14
14
|
: Reducer(list_of_points) {
|
|
15
15
|
this->tolerance = tolerance * tolerance;
|
|
16
16
|
}
|
|
@@ -18,11 +18,11 @@ VisvalingamReducer::VisvalingamReducer(std::vector<Point*>& list_of_points, floa
|
|
|
18
18
|
VisvalingamReducer::~VisvalingamReducer() {}
|
|
19
19
|
|
|
20
20
|
void VisvalingamReducer::reduce() {
|
|
21
|
-
std::vector<Point
|
|
21
|
+
std::vector<Point> new_points = this->simplify();
|
|
22
22
|
points.assign(new_points.begin(), new_points.end());
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
std::vector<Point
|
|
25
|
+
std::vector<Point> VisvalingamReducer::simplify() {
|
|
26
26
|
Vertex* vwLine = Vertex::buildLine(points);
|
|
27
27
|
float minArea = this->tolerance;
|
|
28
28
|
for (;;) {
|
|
@@ -17,21 +17,21 @@ struct Point;
|
|
|
17
17
|
|
|
18
18
|
class VisvalingamReducer : public Reducer {
|
|
19
19
|
public:
|
|
20
|
-
VisvalingamReducer(std::vector<Point
|
|
20
|
+
VisvalingamReducer(std::vector<Point>& list_of_points, float tolerance);
|
|
21
21
|
virtual ~VisvalingamReducer();
|
|
22
22
|
void reduce();
|
|
23
|
-
std::vector<Point
|
|
23
|
+
std::vector<Point> simplify();
|
|
24
24
|
|
|
25
25
|
class Triangle {
|
|
26
26
|
public:
|
|
27
|
-
static int area(Point
|
|
28
|
-
return std::abs(((c
|
|
27
|
+
static int area(const Point& a, const Point& b, const Point& c) {
|
|
28
|
+
return std::abs(((c.x - a.x) * (b.y - a.y) - (b.x - a.x) * (c.y - a.y)) / 2);
|
|
29
29
|
}
|
|
30
30
|
};
|
|
31
31
|
|
|
32
32
|
class Vertex {
|
|
33
33
|
const float MAX_AREA = std::numeric_limits<float>::max();
|
|
34
|
-
explicit Vertex(Point
|
|
34
|
+
explicit Vertex(const Point& pt) {
|
|
35
35
|
this->pt = pt;
|
|
36
36
|
this->prev = nullptr;
|
|
37
37
|
this->next = nullptr;
|
|
@@ -40,7 +40,7 @@ class VisvalingamReducer : public Reducer {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
public:
|
|
43
|
-
Point
|
|
43
|
+
Point pt;
|
|
44
44
|
void setNext(Vertex* nextp) { this->next = nextp; }
|
|
45
45
|
void setPrec(Vertex* prev) { this->prev = prev; }
|
|
46
46
|
void updateArea() {
|
|
@@ -54,10 +54,10 @@ class VisvalingamReducer : public Reducer {
|
|
|
54
54
|
Vertex* get_next() { return this->next; }
|
|
55
55
|
bool isLiving() { return this->isLive; }
|
|
56
56
|
|
|
57
|
-
static Vertex* buildLine(std::vector<Point
|
|
57
|
+
static Vertex* buildLine(std::vector<Point>& pts) {
|
|
58
58
|
Vertex* first = nullptr;
|
|
59
59
|
Vertex* prev = nullptr;
|
|
60
|
-
for (Point
|
|
60
|
+
for (const Point& p : pts) {
|
|
61
61
|
Vertex* v = new Vertex(p);
|
|
62
62
|
if (!first) first = v;
|
|
63
63
|
v->setPrec(prev);
|
|
@@ -88,8 +88,8 @@ class VisvalingamReducer : public Reducer {
|
|
|
88
88
|
return result;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
static std::vector<Point
|
|
92
|
-
std::vector<Point
|
|
91
|
+
static std::vector<Point> getCoordinates(Vertex* head) {
|
|
92
|
+
std::vector<Point> coords;
|
|
93
93
|
Vertex* curr = head;
|
|
94
94
|
while (curr) {
|
|
95
95
|
coords.push_back(curr->pt);
|
|
@@ -27,8 +27,6 @@
|
|
|
27
27
|
#include "PolygonFinder/src/polygon/finder/List.h"
|
|
28
28
|
#include "PolygonFinder/src/polygon/finder/Lists.cpp"
|
|
29
29
|
#include "PolygonFinder/src/polygon/finder/Lists.h"
|
|
30
|
-
#include "PolygonFinder/src/polygon/finder/PointPool.h"
|
|
31
|
-
#include "PolygonFinder/src/polygon/finder/PointPool.cpp"
|
|
32
30
|
#include "PolygonFinder/src/polygon/finder/Polygon.h"
|
|
33
31
|
#include "PolygonFinder/src/polygon/bitmaps/Bitmap.h"
|
|
34
32
|
#include "PolygonFinder/src/polygon/bitmaps/Bitmap.cpp"
|
|
@@ -186,24 +184,25 @@ class To_Ruby<ProcessResult*>
|
|
|
186
184
|
return_me[Symbol("named_sequence")] = pr->named_sequence;
|
|
187
185
|
return_me[Symbol("width")] = pr->width;
|
|
188
186
|
return_me[Symbol("height")] = pr->height;
|
|
187
|
+
return_me[Symbol("versus")] = Symbol(pr->versus == Node::O ? "o" : "a");
|
|
189
188
|
|
|
190
189
|
Rice::Array out;
|
|
191
190
|
for (Polygon& x : pr->polygons)
|
|
192
191
|
{ Rice::Hash poly_hash = Rice::Hash();
|
|
193
|
-
// OUTER: std::vector<Point
|
|
192
|
+
// OUTER: std::vector<Point>
|
|
194
193
|
Rice::Array outer_flat;
|
|
195
|
-
for (Point
|
|
196
|
-
outer_flat.push(p
|
|
197
|
-
outer_flat.push(p
|
|
194
|
+
for (const Point& p : x.outer) {
|
|
195
|
+
outer_flat.push(p.x);
|
|
196
|
+
outer_flat.push(p.y);
|
|
198
197
|
}
|
|
199
198
|
poly_hash[Symbol("outer")] = outer_flat;
|
|
200
|
-
// INNER: std::list<std::vector<Point
|
|
199
|
+
// INNER: std::list<std::vector<Point>>
|
|
201
200
|
Rice::Array inner_collection;
|
|
202
|
-
for (const std::vector<Point
|
|
201
|
+
for (const std::vector<Point>& sequence : x.inner) {
|
|
203
202
|
Rice::Array sequence_flat;
|
|
204
|
-
for (Point
|
|
205
|
-
sequence_flat.push(p
|
|
206
|
-
sequence_flat.push(p
|
|
203
|
+
for (const Point& p : sequence) {
|
|
204
|
+
sequence_flat.push(p.x);
|
|
205
|
+
sequence_flat.push(p.y);
|
|
207
206
|
}
|
|
208
207
|
inner_collection.push(sequence_flat);
|
|
209
208
|
}
|
|
@@ -251,6 +250,7 @@ ProcessResult ruby_result_to_process_result(Rice::Object rb_result) {
|
|
|
251
250
|
Rice::Hash metadata = rb_result.iv_get("@metadata_storage");
|
|
252
251
|
pr.width = detail::From_Ruby<int>().convert(metadata[Symbol("width")].value());
|
|
253
252
|
pr.height = detail::From_Ruby<int>().convert(metadata[Symbol("height")].value());
|
|
253
|
+
pr.versus = metadata[Symbol("versus")] == Symbol("o") ? Node::O : Node::A;
|
|
254
254
|
|
|
255
255
|
Rice::Array rb_polygons = rb_result.iv_get("@polygons_storage");
|
|
256
256
|
for (size_t i = 0; i < rb_polygons.size(); ++i) {
|
|
@@ -270,17 +270,17 @@ ProcessResult ruby_result_to_process_result(Rice::Object rb_result) {
|
|
|
270
270
|
for (size_t j = 0; j < outer_flat.size(); j += 2) {
|
|
271
271
|
int px = detail::From_Ruby<int>().convert(outer_flat[j].value());
|
|
272
272
|
int py = detail::From_Ruby<int>().convert(outer_flat[j+1].value());
|
|
273
|
-
poly.outer.push_back(
|
|
273
|
+
poly.outer.push_back(Point(px, py));
|
|
274
274
|
}
|
|
275
275
|
// INNER
|
|
276
276
|
Rice::Array inner_collection = (Rice::Array)rb_poly[Symbol("inner")];
|
|
277
277
|
for (size_t j = 0; j < inner_collection.size(); ++j) {
|
|
278
278
|
Rice::Array sequence_flat = (Rice::Array)inner_collection[j];
|
|
279
|
-
std::vector<Point
|
|
279
|
+
std::vector<Point> hole;
|
|
280
280
|
for (size_t k = 0; k < sequence_flat.size(); k += 2) {
|
|
281
281
|
int px = detail::From_Ruby<int>().convert(sequence_flat[k].value());
|
|
282
282
|
int py = detail::From_Ruby<int>().convert(sequence_flat[k+1].value());
|
|
283
|
-
hole.push_back(
|
|
283
|
+
hole.push_back(Point(px, py));
|
|
284
284
|
}
|
|
285
285
|
poly.inner.push_back(hole);
|
|
286
286
|
}
|
|
@@ -89,6 +89,17 @@ module Contrek
|
|
|
89
89
|
puts
|
|
90
90
|
end
|
|
91
91
|
|
|
92
|
+
def transpose!
|
|
93
|
+
transposed = ""
|
|
94
|
+
w.times do |x|
|
|
95
|
+
h.times do |y|
|
|
96
|
+
transposed += value_at(x, y)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
@raw = transposed
|
|
100
|
+
@module = h
|
|
101
|
+
end
|
|
102
|
+
|
|
92
103
|
private
|
|
93
104
|
|
|
94
105
|
def next_color(color)
|
|
@@ -102,9 +102,6 @@ module Contrek
|
|
|
102
102
|
if act_part.is?(Part::EXCLUSIVE)
|
|
103
103
|
return if act_part.size == 0
|
|
104
104
|
while (position = act_part.next_position)
|
|
105
|
-
return if outer_joined_polyline.size > 1 &&
|
|
106
|
-
outer_joined_polyline.head.payload == position.payload &&
|
|
107
|
-
act_part == all_parts.first
|
|
108
105
|
outer_joined_polyline.add(position)
|
|
109
106
|
end
|
|
110
107
|
else
|
|
@@ -10,11 +10,13 @@ module Contrek
|
|
|
10
10
|
ADDED = 2
|
|
11
11
|
|
|
12
12
|
attr_reader :polyline, :touched
|
|
13
|
-
attr_accessor :next, :circular_next, :prev, :type, :dead_end, :inverts,
|
|
13
|
+
attr_accessor :next, :circular_next, :prev, :type, :dead_end, :inverts,
|
|
14
|
+
:trasmuted, :versus, :mirror, :next_seam, :transmutation_skip
|
|
14
15
|
def initialize(type, polyline)
|
|
15
16
|
@type = type
|
|
16
17
|
@polyline = polyline
|
|
17
18
|
@next = nil
|
|
19
|
+
@next_seam = nil
|
|
18
20
|
@circular_next = nil
|
|
19
21
|
@prev = nil
|
|
20
22
|
@dead_end = false
|
|
@@ -23,6 +25,7 @@ module Contrek
|
|
|
23
25
|
@trasmuted = false
|
|
24
26
|
@versus = 0
|
|
25
27
|
@mirror = false
|
|
28
|
+
@transmutation_skip = false
|
|
26
29
|
end
|
|
27
30
|
|
|
28
31
|
def is?(type)
|
|
@@ -80,6 +83,38 @@ module Contrek
|
|
|
80
83
|
end
|
|
81
84
|
end
|
|
82
85
|
|
|
86
|
+
def try_transmutation!
|
|
87
|
+
head_queues = head.end_point.queues
|
|
88
|
+
return if head_queues.size == 1
|
|
89
|
+
other_head_part = head_queues.find { |part| part.polyline.tile == polyline.tile && part != self }
|
|
90
|
+
if other_head_part
|
|
91
|
+
tail_queues = tail.end_point.queues
|
|
92
|
+
if tail_queues.find { |part| part == other_head_part }
|
|
93
|
+
if (other_head_part.tail.payload[:y] == tail.payload[:y] && other_head_part.head.payload[:y] == head.payload[:y]) ||
|
|
94
|
+
(other_head_part.tail.payload[:y] == head.payload[:y] && other_head_part.head.payload[:y] == tail.payload[:y])
|
|
95
|
+
if self.next.nil? && other_head_part.prev.nil?
|
|
96
|
+
self.mirror = true
|
|
97
|
+
end
|
|
98
|
+
else
|
|
99
|
+
self.type = Part::EXCLUSIVE
|
|
100
|
+
self.trasmuted = true
|
|
101
|
+
other_head_part.transmutation_skip = true
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def within?(other)
|
|
108
|
+
self_min, self_max = [head.payload[:y], tail.payload[:y]].minmax
|
|
109
|
+
other_min, other_max = [other.head.payload[:y], other.tail.payload[:y]].minmax
|
|
110
|
+
self_min >= other_min && self_max <= other_max
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def same_length?(other)
|
|
114
|
+
(head.payload[:y] - tail.payload[:y]).abs ==
|
|
115
|
+
(other.head.payload[:y] - other.tail.payload[:y]).abs
|
|
116
|
+
end
|
|
117
|
+
|
|
83
118
|
def continuum_to?(other)
|
|
84
119
|
return [] if size <= 2 && inverts && other.size <= 2 && other.inverts
|
|
85
120
|
return [] if other.head.nil?
|
|
@@ -8,6 +8,8 @@ module Contrek
|
|
|
8
8
|
def initialize(*args, **kwargs, &block)
|
|
9
9
|
super
|
|
10
10
|
@parts = []
|
|
11
|
+
@first_seam = nil
|
|
12
|
+
@last_seam = nil
|
|
11
13
|
end
|
|
12
14
|
|
|
13
15
|
def add_part(new_part)
|
|
@@ -16,8 +18,14 @@ module Contrek
|
|
|
16
18
|
last.next = last.circular_next = new_part if last
|
|
17
19
|
new_part.circular_next = @parts.first
|
|
18
20
|
new_part.prev = last
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
if new_part.is?(Part::SEAM)
|
|
22
|
+
@first_seam ||= new_part
|
|
23
|
+
if !@last_seam.nil?
|
|
24
|
+
@last_seam.next_seam = new_part
|
|
25
|
+
end
|
|
26
|
+
@last_seam = new_part
|
|
27
|
+
new_part.orient!
|
|
28
|
+
end
|
|
21
29
|
end
|
|
22
30
|
|
|
23
31
|
def inspect_parts
|
|
@@ -27,6 +35,8 @@ module Contrek
|
|
|
27
35
|
def partition!
|
|
28
36
|
current_part = nil
|
|
29
37
|
@parts = []
|
|
38
|
+
@first_seam = nil
|
|
39
|
+
@last_seam = nil
|
|
30
40
|
|
|
31
41
|
@raw.each_with_index do |position, n|
|
|
32
42
|
if @tile.tg_border?(position)
|
|
@@ -49,7 +59,7 @@ module Contrek
|
|
|
49
59
|
end
|
|
50
60
|
add_part(current_part)
|
|
51
61
|
|
|
52
|
-
|
|
62
|
+
transmute_parts!
|
|
53
63
|
end
|
|
54
64
|
|
|
55
65
|
private
|
|
@@ -57,28 +67,37 @@ module Contrek
|
|
|
57
67
|
# If there are SEAM parts and one is canceled out by another within the same polyline,
|
|
58
68
|
# meaning that all its points are repeated in another, longer sequence,
|
|
59
69
|
# then the shorter one is converted to EXCLUSIVE and marked as transmuted
|
|
60
|
-
def
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
count = 0
|
|
69
|
-
inside.each do |position|
|
|
70
|
-
inclusion = position.end_point.queues.include?(inside_compare)
|
|
71
|
-
count += 1 if inclusion
|
|
70
|
+
def transmute_parts!
|
|
71
|
+
transpose = tile.cluster.finder.transpose?
|
|
72
|
+
if (current_seam = @first_seam)
|
|
73
|
+
loop do
|
|
74
|
+
if transpose
|
|
75
|
+
transmute_transposed_part(current_seam)
|
|
76
|
+
elsif !current_seam.transmutation_skip
|
|
77
|
+
current_seam.try_transmutation!
|
|
72
78
|
end
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
current_seam = current_seam.next_seam
|
|
80
|
+
break if current_seam.nil?
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def transmute_transposed_part(part)
|
|
86
|
+
if (current_seam = @first_seam)
|
|
87
|
+
loop do
|
|
88
|
+
if current_seam != part
|
|
89
|
+
if part.within?(current_seam)
|
|
90
|
+
if !part.same_length?(current_seam)
|
|
91
|
+
part.type = Part::EXCLUSIVE
|
|
92
|
+
part.trasmuted = true
|
|
93
|
+
part.head.end_point.queues.delete(part)
|
|
94
|
+
part.tail.end_point.queues.delete(part)
|
|
95
|
+
return
|
|
96
|
+
end
|
|
97
|
+
end
|
|
81
98
|
end
|
|
99
|
+
current_seam = current_seam.next_seam
|
|
100
|
+
break if current_seam.nil?
|
|
82
101
|
end
|
|
83
102
|
end
|
|
84
103
|
end
|
|
@@ -51,7 +51,8 @@ module Contrek
|
|
|
51
51
|
benchmarks: format_benchmarks,
|
|
52
52
|
width: @source_bitmap.w,
|
|
53
53
|
height: @source_bitmap.h,
|
|
54
|
-
treemap: (@node_cluster.treemap if @options.has_key?(:treemap))
|
|
54
|
+
treemap: (@node_cluster.treemap if @options.has_key?(:treemap)),
|
|
55
|
+
versus: @options[:versus]
|
|
55
56
|
}
|
|
56
57
|
Result.new(@node_cluster.polygons, metadata)
|
|
57
58
|
end
|
data/lib/contrek/version.rb
CHANGED