contrek 1.0.5 → 1.0.7

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 (109) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -3
  3. data/CHANGELOG.md +25 -0
  4. data/Gemfile.lock +1 -1
  5. data/README.md +133 -33
  6. data/Rakefile +3 -0
  7. data/contrek.gemspec +6 -3
  8. data/ext/cpp_polygon_finder/PolygonFinder/Makefile +44 -0
  9. data/ext/cpp_polygon_finder/PolygonFinder/images/sample_10240x10240.png +0 -0
  10. data/ext/cpp_polygon_finder/PolygonFinder/src/Main.cpp +14 -5
  11. data/ext/cpp_polygon_finder/PolygonFinder/src/Tests.cpp +136 -15
  12. data/ext/cpp_polygon_finder/PolygonFinder/src/Tests.h +5 -4
  13. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/CpuTimer.h +44 -0
  14. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/Bitmap.cpp +8 -0
  15. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/Bitmap.h +3 -4
  16. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/FastPngBitmap.cpp +63 -573
  17. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/FastPngBitmap.h +17 -18
  18. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/RemoteFastPngBitmap.cpp +22 -5
  19. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/RemoteFastPngBitmap.h +4 -8
  20. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/spng.c +6980 -0
  21. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/spng.h +537 -0
  22. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/FinderUtils.cpp +101 -0
  23. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/FinderUtils.h +16 -0
  24. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/List.cpp +0 -3
  25. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/List.h +4 -7
  26. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Lists.cpp +13 -13
  27. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Lists.h +5 -7
  28. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Node.cpp +47 -41
  29. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Node.h +15 -10
  30. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/NodeCluster.cpp +181 -178
  31. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/NodeCluster.h +19 -20
  32. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Polygon.h +20 -0
  33. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/PolygonFinder.cpp +52 -137
  34. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/PolygonFinder.h +85 -16
  35. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/RectBounds.h +39 -0
  36. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/ClippedPolygonFinder.cpp +14 -0
  37. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/ClippedPolygonFinder.h +17 -0
  38. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cluster.cpp +117 -0
  39. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cluster.h +32 -0
  40. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cursor.cpp +344 -0
  41. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cursor.h +46 -0
  42. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/EndPoint.cpp +14 -0
  43. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/EndPoint.h +22 -0
  44. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/FakeCluster.cpp +13 -0
  45. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/FakeCluster.h +17 -0
  46. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Finder.cpp +139 -0
  47. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Finder.h +52 -0
  48. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Hub.cpp +23 -0
  49. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Hub.h +40 -0
  50. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Part.cpp +70 -0
  51. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Part.h +47 -0
  52. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/PartPool.cpp +24 -0
  53. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/PartPool.h +23 -0
  54. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Partitionable.cpp +182 -0
  55. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Partitionable.h +30 -0
  56. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Polyline.cpp +108 -0
  57. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Polyline.h +52 -0
  58. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Poolable.cpp +59 -0
  59. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Poolable.h +52 -0
  60. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Position.cpp +31 -0
  61. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Position.h +25 -0
  62. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Queue.h +36 -0
  63. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Queueable.h +230 -0
  64. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Sequence.cpp +35 -0
  65. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Sequence.h +20 -0
  66. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Shape.cpp +26 -0
  67. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Shape.h +23 -0
  68. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Tile.cpp +105 -0
  69. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Tile.h +56 -0
  70. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/Matcher.cpp +3 -3
  71. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/Matcher.h +5 -8
  72. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/RGBMatcher.h +3 -7
  73. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/RGBNotMatcher.cpp +2 -2
  74. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/RGBNotMatcher.h +4 -8
  75. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/ValueNotMatcher.cpp +2 -2
  76. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/ValueNotMatcher.h +3 -7
  77. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/LinearReducer.cpp +23 -15
  78. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/LinearReducer.h +6 -8
  79. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/Reducer.cpp +2 -5
  80. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/Reducer.h +4 -8
  81. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/UniqReducer.cpp +9 -12
  82. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/UniqReducer.h +3 -7
  83. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/VisvalingamReducer.cpp +26 -27
  84. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/VisvalingamReducer.h +76 -87
  85. data/ext/cpp_polygon_finder/cpp_polygon_finder.cpp +167 -138
  86. data/ext/cpp_polygon_finder/extconf.rb +14 -0
  87. data/lib/contrek/bitmaps/sample_generator.rb +56 -0
  88. data/lib/contrek/cpp/cpp_concurrent_finder.rb +9 -0
  89. data/lib/contrek/finder/bounds.rb +17 -0
  90. data/lib/contrek/finder/concurrent/cluster.rb +2 -2
  91. data/lib/contrek/finder/concurrent/cursor.rb +8 -8
  92. data/lib/contrek/finder/concurrent/finder.rb +19 -15
  93. data/lib/contrek/finder/concurrent/part.rb +2 -2
  94. data/lib/contrek/finder/concurrent/partitionable.rb +1 -1
  95. data/lib/contrek/finder/concurrent/polyline.rb +17 -15
  96. data/lib/contrek/finder/concurrent/sequence.rb +11 -0
  97. data/lib/contrek/finder/concurrent/tile.rb +3 -3
  98. data/lib/contrek/finder/node_cluster.rb +16 -8
  99. data/lib/contrek/finder/polygon_finder.rb +9 -10
  100. data/lib/contrek/finder/result.rb +13 -0
  101. data/lib/contrek/results/cpp_result.rb +21 -0
  102. data/lib/contrek/version.rb +1 -1
  103. data/lib/contrek.rb +11 -1
  104. metadata +59 -10
  105. data/ext/cpp_polygon_finder/PolygonFinder/.cproject +0 -136
  106. data/ext/cpp_polygon_finder/PolygonFinder/.project +0 -27
  107. data/ext/cpp_polygon_finder/PolygonFinder/.settings/org.eclipse.ltk.core.refactoring.prefs +0 -2
  108. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/PngBitmap.cpp +0 -48
  109. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/PngBitmap.h +0 -32
@@ -9,28 +9,28 @@
9
9
  #include "Lists.h"
10
10
  #include "List.h"
11
11
  #include <list>
12
+ #include <vector>
12
13
  struct Link;
13
14
  class List;
14
- Lists::Lists() {
15
- this->lists = new std::list<List*>();
16
- }
17
15
 
18
16
  Lists::~Lists() {
17
+ for (auto* list : this->lists)
18
+ { delete list;
19
+ }
19
20
  }
20
21
 
21
22
  List *Lists::add_list() {
22
- List *list = new List(this->lists->size());
23
- lists->push_back(list);
23
+ List *list = new List(this->lists.size());
24
+ lists.push_back(list);
24
25
  return(list);
25
26
  }
26
27
 
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;
28
+ std::vector<Link> Lists::get_data_pointer() {
29
+ std::vector<Link> data(this->lists.size());
30
+ for (auto& dt : data) {
31
+ dt.inside = false;
32
+ dt.next = nullptr;
33
+ dt.prev = nullptr;
34
34
  }
35
- return(data_pointer);
35
+ return data;
36
36
  }
@@ -6,9 +6,9 @@
6
6
  * Copyright 2025 Emanuele Cesaroni
7
7
  */
8
8
 
9
- #ifndef POLYGON_FINDER_LISTS_H_
10
- #define POLYGON_FINDER_LISTS_H_
9
+ #pragma once
11
10
  #include <list>
11
+ #include <vector>
12
12
  #include "List.h"
13
13
  class List;
14
14
  class Listable;
@@ -19,12 +19,10 @@ struct Link {
19
19
 
20
20
  class Lists {
21
21
  public:
22
- Lists();
22
+ Lists() {}
23
23
  virtual ~Lists();
24
24
  List *add_list();
25
- Link *get_data_pointer();
25
+ std::vector<Link> get_data_pointer();
26
26
  private:
27
- std::list<List*> *lists;
27
+ std::list<List*> lists;
28
28
  };
29
-
30
- #endif /* POLYGON_FINDER_LISTS_H_ */
@@ -6,13 +6,13 @@
6
6
  * Copyright 2025 Emanuele Cesaroni
7
7
  */
8
8
 
9
- #include "Node.h"
10
- #include <string>
11
9
  #include <string.h>
10
+ #include <string>
12
11
  #include <iostream>
13
12
  #include <algorithm>
14
13
  #include <vector>
15
14
  #include <list>
15
+ #include "Node.h"
16
16
 
17
17
  Node::Node(int min_x, int max_x, int y, char name) {
18
18
  this->name = name;
@@ -28,9 +28,6 @@ Node::Node(int min_x, int max_x, int y, char name) {
28
28
  this->inner_index = -1;
29
29
  }
30
30
 
31
- Node::~Node() {
32
- }
33
-
34
31
  bool Node::get_trackmax() {
35
32
  return((this->track & OMAX) != 0);
36
33
  }
@@ -44,39 +41,48 @@ bool Node::track_uncomplete() {
44
41
  bool Node::tangs_with(Node *node) {
45
42
  return(this->min_x <= node->max_x && node->min_x <= this->max_x);
46
43
  }
44
+
47
45
  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
- }
46
+ if (other_node->y < this->y) tangs[T_UP].push_back(other_node);
47
+ else tangs[T_DOWN].push_back(other_node);
53
48
  }
54
49
 
55
- void Node::precalc_tangs_sequences() {
56
- this->tangs_sequence = new std::vector<NodeDescriptor*>(tangs[T_UP].size() + tangs[T_DOWN].size());
50
+ void Node::precalc_tangs_sequences(std::vector<Point>& points) {
51
+ this->tangs_sequence.clear();
52
+ this->tangs_sequence.reserve(tangs[T_UP].size() + tangs[T_DOWN].size());
53
+ std::vector<Node*> up_copy = tangs[T_UP];
54
+ std::vector<Node*> down_copy = tangs[T_DOWN];
55
+
56
+ // --- CLOCKWISE (UP) ---
57
+ std::sort(up_copy.begin(), up_copy.end(), sort_min_x);
58
+ if (!up_copy.empty()) {
59
+ this->up_indexer = -up_copy.front()->abs_x_index;
60
+ }
61
+ for (Node* t_node : up_copy) {
62
+ tangs_sequence.push_back(NodeDescriptor{
63
+ t_node,
64
+ Tangent{ &points.emplace_back(t_node->max_x, t_node->y), OMAX},
65
+ Tangent{ &points.emplace_back(t_node->min_x, t_node->y), OMIN}
66
+ });
67
+ }
57
68
 
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})});
69
+ // --- COUNTER-CLOCKWISE (DOWN) ---
70
+ std::sort(down_copy.begin(), down_copy.end(), sort_max_x);
71
+ std::reverse(down_copy.begin(), down_copy.end());
72
+ if (!down_copy.empty()) {
73
+ this->down_indexer = (down_copy.back()->abs_x_index +
74
+ tangs[T_UP].size() + tangs[T_DOWN].size() - 1);
68
75
  }
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})});
76
+ for (Node* t_node : down_copy) {
77
+ tangs_sequence.push_back(NodeDescriptor{
78
+ t_node,
79
+ Tangent{&points.emplace_back(t_node->min_x, t_node->y), OMIN},
80
+ Tangent{&points.emplace_back(t_node->max_x, t_node->y), OMAX}
81
+ });
77
82
  }
78
- this->tangs_count = this->tangs_sequence->size();
83
+ this->tangs_count = this->tangs_sequence.size();
79
84
  }
85
+
80
86
  bool Node::sort_min_x(Node *a, Node *b) {
81
87
  return(a->min_x <= b->min_x);
82
88
  }
@@ -87,25 +93,25 @@ Node* Node::my_next_inner(Node *last, int versus) {
87
93
  unsigned int last_node_index;
88
94
  if (last->y < this->y) last_node_index = last->abs_x_index + this->up_indexer;
89
95
  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);
96
+ if (versus == Node::O) last_node_index == 0 ? last_node_index = this->tangs_sequence.size() - 1 : last_node_index--;
97
+ else last_node_index == this->tangs_sequence.size() - 1 ? last_node_index = 0 : last_node_index++;
98
+ return((this->tangs_sequence)[last_node_index].node);
93
99
  }
94
100
  Node* Node::my_next_outer(Node *last, int versus) {
95
101
  unsigned int last_node_index;
96
102
  if (last->y < this->y) last_node_index = last->abs_x_index + this->up_indexer;
97
103
  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);
104
+ if (versus == Node::O) last_node_index == this->tangs_sequence.size() - 1 ? last_node_index = 0 : last_node_index++;
105
+ else last_node_index == 0 ? last_node_index = this->tangs_sequence.size() - 1 : last_node_index--;
106
+ return((this->tangs_sequence)[last_node_index].node);
101
107
  }
102
108
 
103
109
  Point* Node::coords_entering_to(Node *enter_to, int mode, int tracking) {
104
110
  int enter_to_index;
105
111
  if (enter_to->y < this->y) enter_to_index = enter_to->abs_x_index + this->up_indexer;
106
112
  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);
113
+ NodeDescriptor ds = (this->tangs_sequence)[enter_to_index];
114
+ Tangent t = (mode == Node::O ? ds.o : ds.a);
115
+ enter_to->track |= TURNER[tracking][t.mode - 1];
116
+ return(t.point);
111
117
  }
@@ -6,17 +6,24 @@
6
6
  * Copyright 2025 Emanuele Cesaroni
7
7
  */
8
8
 
9
- #ifndef POLYGON_FINDER_NODE_H_
10
- #define POLYGON_FINDER_NODE_H_
9
+ #pragma once
11
10
  #include <string>
12
11
  #include <vector>
13
12
  #include <list>
14
13
  #include <map>
15
14
  #include "List.h"
16
15
 
16
+ class NodeCluster;
17
17
  struct Point {
18
18
  int x;
19
19
  int y;
20
+ std::string toString() const {
21
+ return "[x:" + std::to_string(x) + ",y:" + std::to_string(y) + "]";
22
+ }
23
+ bool operator==(const Point& other) const {
24
+ return x == other.x && y == other.y;
25
+ }
26
+ Point(int x_, int y_) : x(x_), y(y_) {}
20
27
  };
21
28
  struct Tangent {
22
29
  Point *point;
@@ -42,7 +49,7 @@ class Node : public Listable {
42
49
  static const int OUTER = 0;
43
50
  static const int INNER = 1;
44
51
 
45
- std::list<Node*> tangs[2];
52
+ std::vector<Node*> tangs[2];
46
53
  int y;
47
54
  int abs_x_index;
48
55
  int up_indexer, down_indexer;
@@ -52,7 +59,7 @@ class Node : public Listable {
52
59
  int outer_index, inner_index;
53
60
  bool tangs_with(Node *node);
54
61
  void add_intersection(Node *other_node);
55
- std::vector<NodeDescriptor*> *tangs_sequence;
62
+ std::vector<NodeDescriptor> tangs_sequence;
56
63
  Point* coords_entering_to(Node *enter_to, int mode, int tracking);
57
64
  Node* my_next_outer(Node *last, int versus);
58
65
  Node* my_next_inner(Node *last, int versus);
@@ -67,14 +74,12 @@ class Node : public Listable {
67
74
  public:
68
75
  int min_x, max_x;
69
76
  Node(int min_x, int max_x, int y, char name);
70
- virtual ~Node();
71
- void precalc_tangs_sequences();
77
+ void precalc_tangs_sequences(std::vector<Point>& points);
78
+ bool processed = false;
72
79
  };
73
80
 
74
81
  struct NodeDescriptor {
75
82
  Node *node;
76
- Tangent *a;
77
- Tangent *o;
83
+ Tangent a;
84
+ Tangent o;
78
85
  };
79
-
80
- #endif /* POLYGON_FINDER_NODE_H_ */