contrek 1.0.0

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 (78) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.rspec +3 -0
  4. data/Gemfile +3 -0
  5. data/Gemfile.lock +84 -0
  6. data/LICENSE.md +9 -0
  7. data/README.md +118 -0
  8. data/Rakefile +19 -0
  9. data/contrek.gemspec +23 -0
  10. data/contrek.png +0 -0
  11. data/ext/cpp_polygon_finder/PolygonFinder/.cproject +136 -0
  12. data/ext/cpp_polygon_finder/PolygonFinder/.project +27 -0
  13. data/ext/cpp_polygon_finder/PolygonFinder/.settings/org.eclipse.ltk.core.refactoring.prefs +2 -0
  14. data/ext/cpp_polygon_finder/PolygonFinder/images/labyrinth.png +0 -0
  15. data/ext/cpp_polygon_finder/PolygonFinder/src/Main.cpp +41 -0
  16. data/ext/cpp_polygon_finder/PolygonFinder/src/Tests.cpp +69 -0
  17. data/ext/cpp_polygon_finder/PolygonFinder/src/Tests.h +19 -0
  18. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/Bitmap.cpp +52 -0
  19. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/Bitmap.h +32 -0
  20. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/FastPngBitmap.cpp +656 -0
  21. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/FastPngBitmap.h +42 -0
  22. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/PngBitmap.cpp +48 -0
  23. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/PngBitmap.h +32 -0
  24. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/RemoteFastPngBitmap.cpp +30 -0
  25. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/RemoteFastPngBitmap.h +26 -0
  26. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/X_picopng.cpp +576 -0
  27. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/List.cpp +120 -0
  28. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/List.h +40 -0
  29. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Lists.cpp +36 -0
  30. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Lists.h +30 -0
  31. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Node.cpp +111 -0
  32. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Node.h +80 -0
  33. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/NodeCluster.cpp +325 -0
  34. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/NodeCluster.h +59 -0
  35. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/PolygonFinder.cpp +206 -0
  36. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/PolygonFinder.h +69 -0
  37. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/optionparser.h +2858 -0
  38. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/Matcher.cpp +23 -0
  39. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/Matcher.h +23 -0
  40. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/RGBMatcher.cpp +20 -0
  41. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/RGBMatcher.h +23 -0
  42. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/RGBNotMatcher.cpp +20 -0
  43. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/RGBNotMatcher.h +23 -0
  44. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/ValueNotMatcher.cpp +20 -0
  45. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/ValueNotMatcher.h +21 -0
  46. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/LinearReducer.cpp +40 -0
  47. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/LinearReducer.h +23 -0
  48. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/Reducer.cpp +19 -0
  49. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/Reducer.h +25 -0
  50. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/UniqReducer.cpp +30 -0
  51. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/UniqReducer.h +21 -0
  52. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/VisvalingamReducer.cpp +50 -0
  53. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/VisvalingamReducer.h +121 -0
  54. data/ext/cpp_polygon_finder/cpp_polygon_finder.cpp +260 -0
  55. data/ext/cpp_polygon_finder/extconf.rb +2 -0
  56. data/lib/contrek/bitmaps/bitmap.rb +21 -0
  57. data/lib/contrek/bitmaps/chunky_bitmap.rb +33 -0
  58. data/lib/contrek/bitmaps/painting.rb +40 -0
  59. data/lib/contrek/bitmaps/png_bitmap.rb +62 -0
  60. data/lib/contrek/bitmaps/rgb_color.rb +25 -0
  61. data/lib/contrek/finder/list.rb +132 -0
  62. data/lib/contrek/finder/list_entry.rb +11 -0
  63. data/lib/contrek/finder/listable.rb +8 -0
  64. data/lib/contrek/finder/lists.rb +25 -0
  65. data/lib/contrek/finder/node.rb +126 -0
  66. data/lib/contrek/finder/node_cluster.rb +294 -0
  67. data/lib/contrek/finder/polygon_finder.rb +121 -0
  68. data/lib/contrek/map/mercator_projection.rb +76 -0
  69. data/lib/contrek/matchers/matcher.rb +20 -0
  70. data/lib/contrek/matchers/matcher_hsb.rb +24 -0
  71. data/lib/contrek/matchers/value_not_matcher.rb +9 -0
  72. data/lib/contrek/reducers/linear_reducer.rb +25 -0
  73. data/lib/contrek/reducers/reducer.rb +14 -0
  74. data/lib/contrek/reducers/uniq_reducer.rb +9 -0
  75. data/lib/contrek/reducers/visvalingam_reducer.rb +139 -0
  76. data/lib/contrek/version.rb +3 -0
  77. data/lib/contrek.rb +58 -0
  78. metadata +175 -0
@@ -0,0 +1,120 @@
1
+ /*
2
+ * List.cpp
3
+ *
4
+ * Created on: 08 gen 2019
5
+ * Author: ema
6
+ * Copyright 2025 Emanuele Cesaroni
7
+ */
8
+
9
+ #include "List.h"
10
+ #include <iostream>
11
+
12
+ class Listable;
13
+
14
+ List::List(int id) {
15
+ this->start = nullptr;
16
+ this->end = nullptr;
17
+ this->isize = 0;
18
+ this->idd = id;
19
+ }
20
+
21
+ List::~List() {
22
+ }
23
+
24
+ Listable *List::first() {
25
+ return(this->start);
26
+ }
27
+ Listable *List::last() {
28
+ return(this->end);
29
+ }
30
+
31
+ bool List::contains(Listable *entry) {
32
+ return(entry->data_pointer[this->idd].inside);
33
+ }
34
+ int List::get_id() {
35
+ return(this->idd);
36
+ }
37
+
38
+ void List::grab(List *source_list) {
39
+ if (source_list->size() == 0) return;
40
+ int source_list_idd = source_list->get_id();
41
+ Listable *source_list_start_entry = source_list->first();
42
+
43
+ Listable *act = source_list->last();
44
+ while (true)
45
+ { if ((act = act->data_pointer[source_list_idd].prev) == nullptr) break;
46
+ }
47
+ Listable *source_entry = source_list->first();
48
+ while (true)
49
+ { source_entry->data_pointer[this->idd] = source_entry->data_pointer[source_list_idd];
50
+ Listable *next_entry = source_entry->data_pointer[source_list_idd].next;
51
+ source_entry->data_pointer[source_list_idd].inside = false;
52
+ source_entry->data_pointer[source_list_idd].next = nullptr;
53
+ source_entry->data_pointer[source_list_idd].prev = nullptr;
54
+ if (next_entry == nullptr) break;
55
+ source_entry = next_entry;
56
+ }
57
+ source_list_start_entry->data_pointer[this->idd].prev = this->end;
58
+ if (this->end != nullptr) this->end->data_pointer[this->idd].next = source_list_start_entry;
59
+ this->end = source_list->last();
60
+ if (this->start == nullptr) this->start = source_list->first();
61
+ this->isize += source_list->size();
62
+ source_list->reset();
63
+ }
64
+
65
+ void List::reset() {
66
+ this->end = nullptr;
67
+ this->start = nullptr;
68
+ this->isize = 0;
69
+ }
70
+
71
+ Listable *List::shift() {
72
+ if (this->isize == 0) return(nullptr);
73
+ Listable *retme = this->start;
74
+ Listable *next_of_retme = retme->data_pointer[this->idd].next;
75
+ this->start = next_of_retme;
76
+ if (retme == this->end) this->end = nullptr;
77
+ if (next_of_retme != nullptr) next_of_retme->data_pointer[this->idd].prev = nullptr;
78
+ this->isize--;
79
+ retme->data_pointer[this->idd].next = nullptr;
80
+ retme->data_pointer[this->idd].prev = nullptr;
81
+ retme->data_pointer[this->idd].inside = false;
82
+ return (retme);
83
+ }
84
+
85
+ void List::push_back(Listable *entry) {
86
+ if (entry->data_pointer[this->idd].inside) return;
87
+ if (this->isize > 0)
88
+ { this->end->data_pointer[this->idd].next = entry;
89
+ entry->data_pointer[this->idd].prev = this->end;
90
+ } else {
91
+ this->start = entry;
92
+ }
93
+ this->end = entry;
94
+ entry->data_pointer[this->idd].inside = true;
95
+ this->isize++;
96
+ }
97
+ int List::size() {
98
+ return(this->isize);
99
+ }
100
+
101
+ void List::remove(Listable *entry) {
102
+ if (this->isize == 0) return;
103
+ if (entry->data_pointer[this->idd].inside == false) return;
104
+ Listable *next_of_entry = entry->data_pointer[this->idd].next;
105
+ Listable *prev_of_entry = entry->data_pointer[this->idd].prev;
106
+
107
+ if (entry == this->start)
108
+ { this->start = next_of_entry;
109
+ }
110
+ if (entry == this->end)
111
+ { this->end = prev_of_entry;
112
+ }
113
+
114
+ if (next_of_entry != nullptr) next_of_entry->data_pointer[this->idd].prev = prev_of_entry;
115
+ if (prev_of_entry != nullptr) prev_of_entry->data_pointer[this->idd].next = next_of_entry;
116
+ entry->data_pointer[this->idd].next = nullptr;
117
+ entry->data_pointer[this->idd].prev = nullptr;
118
+ this->isize--;
119
+ entry->data_pointer[this->idd].inside = false;
120
+ }
@@ -0,0 +1,40 @@
1
+ /*
2
+ * List.h
3
+ *
4
+ * Created on: 08 gen 2019
5
+ * Author: ema
6
+ * Copyright 2025 Emanuele Cesaroni
7
+ */
8
+
9
+ #ifndef POLYGON_FINDER_LIST_H_
10
+ #define POLYGON_FINDER_LIST_H_
11
+
12
+ #include "Lists.h"
13
+ struct Link;
14
+ class Listable {
15
+ public:
16
+ Link *data_pointer;
17
+ };
18
+
19
+ class List {
20
+ public:
21
+ List(int id);
22
+ virtual ~List();
23
+ void push_back(Listable *entry);
24
+ void remove(Listable *entry);
25
+ void grab(List *source_list);
26
+ int size();
27
+ Listable *first();
28
+ Listable *last();
29
+ Listable *shift();
30
+ void reset();
31
+ bool contains(Listable *entry);
32
+ int get_id();
33
+ private:
34
+ Listable *start;
35
+ Listable *end;
36
+ int isize;
37
+ int idd;
38
+ };
39
+
40
+ #endif /* POLYGON_FINDER_LIST_H_ */
@@ -0,0 +1,36 @@
1
+ /*
2
+ * Lists.cpp
3
+ *
4
+ * Created on: 08 gen 2019
5
+ * Author: ema
6
+ * Copyright 2025 Emanuele Cesaroni
7
+ */
8
+
9
+ #include "Lists.h"
10
+ #include "List.h"
11
+ #include <list>
12
+ struct Link;
13
+ class List;
14
+ Lists::Lists() {
15
+ this->lists = new std::list<List*>();
16
+ }
17
+
18
+ Lists::~Lists() {
19
+ }
20
+
21
+ List *Lists::add_list() {
22
+ List *list = new List(this->lists->size());
23
+ lists->push_back(list);
24
+ return(list);
25
+ }
26
+
27
+ Link *Lists::get_data_pointer() {
28
+ Link *data_pointer = new Link[this->lists->size()];
29
+ Link *dt = data_pointer;
30
+ for (unsigned int i = 0; i < this->lists->size(); ++i, dt++)
31
+ { dt->inside = false;
32
+ dt->next = nullptr;
33
+ dt->prev = nullptr;
34
+ }
35
+ return(data_pointer);
36
+ }
@@ -0,0 +1,30 @@
1
+ /*
2
+ * Lists.h
3
+ *
4
+ * Created on: 08 gen 2019
5
+ * Author: ema
6
+ * Copyright 2025 Emanuele Cesaroni
7
+ */
8
+
9
+ #ifndef POLYGON_FINDER_LISTS_H_
10
+ #define POLYGON_FINDER_LISTS_H_
11
+ #include <list>
12
+ #include "List.h"
13
+ class List;
14
+ class Listable;
15
+ struct Link {
16
+ Listable *next, *prev;
17
+ bool inside;
18
+ };
19
+
20
+ class Lists {
21
+ public:
22
+ Lists();
23
+ virtual ~Lists();
24
+ List *add_list();
25
+ Link *get_data_pointer();
26
+ private:
27
+ std::list<List*> *lists;
28
+ };
29
+
30
+ #endif /* POLYGON_FINDER_LISTS_H_ */
@@ -0,0 +1,111 @@
1
+ /*
2
+ * Node.cpp
3
+ *
4
+ * Created on: 26 nov 2018
5
+ * Author: ema
6
+ * Copyright 2025 Emanuele Cesaroni
7
+ */
8
+
9
+ #include "Node.h"
10
+ #include <string>
11
+ #include <string.h>
12
+ #include <iostream>
13
+ #include <algorithm>
14
+ #include <vector>
15
+ #include <list>
16
+
17
+ Node::Node(int min_x, int max_x, int y, char name) {
18
+ this->name = name;
19
+ this->min_x = min_x;
20
+ this->max_x = max_x;
21
+ this->y = y;
22
+ this->tangs_count = 0;
23
+ this->abs_x_index = 0;
24
+ this->down_indexer = 0;
25
+ this->up_indexer = 0;
26
+ this->track = 0;
27
+ this->outer_index = -1;
28
+ this->inner_index = -1;
29
+ }
30
+
31
+ Node::~Node() {
32
+ }
33
+
34
+ bool Node::get_trackmax() {
35
+ return((this->track & OMAX) != 0);
36
+ }
37
+ bool Node::track_complete() {
38
+ return((this->track & OCOMPLETE) == OCOMPLETE);
39
+ }
40
+ bool Node::track_uncomplete() {
41
+ return((this->track & OCOMPLETE) != OCOMPLETE);
42
+ }
43
+
44
+ bool Node::tangs_with(Node *node) {
45
+ return(this->min_x <= node->max_x && node->min_x <= this->max_x);
46
+ }
47
+ void Node::add_intersection(Node *other_node) {
48
+ if (other_node->y < this->y)
49
+ { tangs[T_UP].push_back(other_node);
50
+ } else {
51
+ tangs[T_DOWN].push_back(other_node);
52
+ }
53
+ }
54
+
55
+ void Node::precalc_tangs_sequences() {
56
+ this->tangs_sequence = new std::vector<NodeDescriptor*>(tangs[T_UP].size() + tangs[T_DOWN].size());
57
+
58
+ std::list<Node*> tangs_seq;
59
+ int n = 0;
60
+ // clockwise
61
+ tangs_seq = tangs[T_UP];
62
+ tangs_seq.sort(sort_min_x);
63
+ if (tangs_seq.size() > 0) this->up_indexer = -tangs_seq.front()->abs_x_index;
64
+ for (std::list<Node*>::iterator t_node = tangs_seq.begin(); t_node != tangs_seq.end(); ++t_node)
65
+ { (*this->tangs_sequence)[n++] = new NodeDescriptor({ *t_node,
66
+ new Tangent({new Point({(*t_node)->max_x, (*t_node)->y}), OMAX}),
67
+ new Tangent({new Point({(*t_node)->min_x, (*t_node)->y}), OMIN})});
68
+ }
69
+ tangs_seq = tangs[T_DOWN];
70
+ tangs_seq.sort(sort_max_x);
71
+ tangs_seq.reverse();
72
+ if (tangs_seq.size() > 0) this->down_indexer = (tangs_seq.back()->abs_x_index + tangs[T_UP].size() + tangs[T_DOWN].size() - 1);
73
+ for (std::list<Node*>::iterator t_node = tangs_seq.begin(); t_node != tangs_seq.end(); ++t_node)
74
+ { (*this->tangs_sequence)[n++] = new NodeDescriptor({ *t_node,
75
+ new Tangent({new Point({(*t_node)->min_x, (*t_node)->y}), OMIN}),
76
+ new Tangent({new Point({(*t_node)->max_x, (*t_node)->y}), OMAX})});
77
+ }
78
+ this->tangs_count = this->tangs_sequence->size();
79
+ }
80
+ bool Node::sort_min_x(Node *a, Node *b) {
81
+ return(a->min_x <= b->min_x);
82
+ }
83
+ bool Node::sort_max_x(Node *a, Node *b) {
84
+ return(a->max_x <= b->max_x);
85
+ }
86
+ Node* Node::my_next_inner(Node *last, int versus) {
87
+ unsigned int last_node_index;
88
+ if (last->y < this->y) last_node_index = last->abs_x_index + this->up_indexer;
89
+ else last_node_index = this->down_indexer - last->abs_x_index;
90
+ if (versus == Node::O) last_node_index == 0 ? last_node_index = this->tangs_sequence->size() - 1 : last_node_index--;
91
+ else last_node_index == this->tangs_sequence->size() - 1 ? last_node_index = 0 : last_node_index++;
92
+ return((*this->tangs_sequence)[last_node_index]->node);
93
+ }
94
+ Node* Node::my_next_outer(Node *last, int versus) {
95
+ unsigned int last_node_index;
96
+ if (last->y < this->y) last_node_index = last->abs_x_index + this->up_indexer;
97
+ else last_node_index = this->down_indexer - last->abs_x_index;
98
+ if (versus == Node::O) last_node_index == this->tangs_sequence->size() - 1 ? last_node_index = 0 : last_node_index++;
99
+ else last_node_index == 0 ? last_node_index = this->tangs_sequence->size() - 1 : last_node_index--;
100
+ return((*this->tangs_sequence)[last_node_index]->node);
101
+ }
102
+
103
+ Point* Node::coords_entering_to(Node *enter_to, int mode, int tracking) {
104
+ int enter_to_index;
105
+ if (enter_to->y < this->y) enter_to_index = enter_to->abs_x_index + this->up_indexer;
106
+ else enter_to_index = this->down_indexer - enter_to->abs_x_index;
107
+ NodeDescriptor *ds = (*this->tangs_sequence)[enter_to_index];
108
+ Tangent *t = (mode == Node::O ? ds->o : ds->a);
109
+ enter_to->track |= TURNER[tracking][t->mode - 1];
110
+ return(t->point);
111
+ }
@@ -0,0 +1,80 @@
1
+ /*
2
+ * Node.h
3
+ *
4
+ * Created on: 26 nov 2018
5
+ * Author: ema
6
+ * Copyright 2025 Emanuele Cesaroni
7
+ */
8
+
9
+ #ifndef POLYGON_FINDER_NODE_H_
10
+ #define POLYGON_FINDER_NODE_H_
11
+ #include <string>
12
+ #include <vector>
13
+ #include <list>
14
+ #include <map>
15
+ #include "List.h"
16
+
17
+ struct Point {
18
+ int x;
19
+ int y;
20
+ };
21
+ struct Tangent {
22
+ Point *point;
23
+ int mode;
24
+ };
25
+ struct NodeDescriptor;
26
+
27
+
28
+ class Node : public Listable {
29
+ public:
30
+ static const int T_UP = 0;
31
+ static const int T_DOWN = 1;
32
+ static const int O = 0;
33
+ static const int A = 1;
34
+ static const int OMAX = 1 << 0;
35
+ static const int OMIN = 1 << 1;
36
+ static const int IMAX = 1 << 2;
37
+ static const int IMIN = 1 << 3;
38
+ static const int OCOMPLETE = OMIN | OMAX;
39
+ static const int TURN_MAX = IMAX | OMAX;
40
+ static const int TURN_MIN = IMIN | OMIN;
41
+ const int TURNER[2][2] = {{OMAX, OMIN}, {TURN_MAX, TURN_MIN}};
42
+ static const int OUTER = 0;
43
+ static const int INNER = 1;
44
+
45
+ std::list<Node*> tangs[2];
46
+ int y;
47
+ int abs_x_index;
48
+ int up_indexer, down_indexer;
49
+ int tangs_count;
50
+ char name;
51
+ int track;
52
+ int outer_index, inner_index;
53
+ bool tangs_with(Node *node);
54
+ void add_intersection(Node *other_node);
55
+ std::vector<NodeDescriptor*> *tangs_sequence;
56
+ Point* coords_entering_to(Node *enter_to, int mode, int tracking);
57
+ Node* my_next_outer(Node *last, int versus);
58
+ Node* my_next_inner(Node *last, int versus);
59
+ bool track_uncomplete();
60
+ bool track_complete();
61
+ bool get_trackmax();
62
+
63
+ private:
64
+ static bool sort_min_x(Node *a, Node *b);
65
+ static bool sort_max_x(Node *a, Node *b);
66
+
67
+ public:
68
+ int min_x, max_x;
69
+ Node(int min_x, int max_x, int y, char name);
70
+ virtual ~Node();
71
+ void precalc_tangs_sequences();
72
+ };
73
+
74
+ struct NodeDescriptor {
75
+ Node *node;
76
+ Tangent *a;
77
+ Tangent *o;
78
+ };
79
+
80
+ #endif /* POLYGON_FINDER_NODE_H_ */