rbpoly2tri 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,126 @@
1
+ /*
2
+ * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
3
+ * http://code.google.com/p/poly2tri/
4
+ *
5
+ * All rights reserved.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without modification,
8
+ * are permitted provided that the following conditions are met:
9
+ *
10
+ * * Redistributions of source code must retain the above copyright notice,
11
+ * this list of conditions and the following disclaimer.
12
+ * * Redistributions in binary form must reproduce the above copyright notice,
13
+ * this list of conditions and the following disclaimer in the documentation
14
+ * and/or other materials provided with the distribution.
15
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
16
+ * used to endorse or promote products derived from this software without specific
17
+ * prior written permission.
18
+ *
19
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ */
31
+ /**
32
+ * Sweep-line, Constrained Delauney Triangulation (CDT) See: Domiter, V. and
33
+ * Zalik, B.(2008)'Sweep-line algorithm for constrained Delaunay triangulation',
34
+ * International Journal of Geographical Information Science
35
+ *
36
+ * "FlipScan" Constrained Edge Algorithm invented by Thomas �hl�n, thahlen@gmail.com
37
+ */
38
+
39
+ #ifndef SWEEP_H
40
+ #define SWEEP_H
41
+
42
+ #include <vector>
43
+
44
+ namespace p2t {
45
+
46
+ class SweepContext;
47
+ struct Node;
48
+ struct Point;
49
+ struct Edge;
50
+ class Triangle;
51
+
52
+ class Sweep {
53
+ public:
54
+
55
+ void Triangulate(SweepContext& tcx);
56
+ ~Sweep();
57
+
58
+ private:
59
+
60
+ void SweepPoints(SweepContext& tcx);
61
+
62
+ Node& PointEvent(SweepContext& tcx, Point& point);
63
+
64
+ void EdgeEvent(SweepContext& tcx, Edge* edge, Node* node);
65
+
66
+ void EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangle, Point& point);
67
+
68
+ Node& NewFrontTriangle(SweepContext& tcx, Point& point, Node& node);
69
+
70
+ void Fill(SweepContext& tcx, Node& node);
71
+
72
+ bool Legalize(SweepContext& tcx, Triangle& t);
73
+
74
+ bool Incircle(Point& pa, Point& pb, Point& pc, Point& pd);
75
+
76
+ void RotateTrianglePair(Triangle& t, Point& p, Triangle& ot, Point& op);
77
+
78
+ void FillAdvancingFront(SweepContext& tcx, Node& n);
79
+
80
+ double HoleAngle(Node& node);
81
+
82
+ double BasinAngle(Node& node);
83
+
84
+ void FillBasin(SweepContext& tcx, Node& node);
85
+
86
+ void FillBasinReq(SweepContext& tcx, Node* node);
87
+
88
+ bool IsShallow(SweepContext& tcx, Node& node);
89
+
90
+ bool IsEdgeSideOfTriangle(Triangle& triangle, Point& ep, Point& eq);
91
+
92
+ void FillEdgeEvent(SweepContext& tcx, Edge* edge, Node* node);
93
+
94
+ void FillRightAboveEdgeEvent(SweepContext& tcx, Edge* edge, Node* node);
95
+
96
+ void FillRightBelowEdgeEvent(SweepContext& tcx, Edge* edge, Node& node);
97
+
98
+ void FillRightConcaveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node);
99
+
100
+ void FillRightConvexEdgeEvent(SweepContext& tcx, Edge* edge, Node& node);
101
+
102
+ void FillLeftAboveEdgeEvent(SweepContext& tcx, Edge* edge, Node* node);
103
+
104
+ void FillLeftBelowEdgeEvent(SweepContext& tcx, Edge* edge, Node& node);
105
+
106
+ void FillLeftConcaveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node);
107
+
108
+ void FillLeftConvexEdgeEvent(SweepContext& tcx, Edge* edge, Node& node);
109
+
110
+ void FlipEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* t, Point& p);
111
+
112
+ Triangle& NextFlipTriangle(SweepContext& tcx, int o, Triangle& t, Triangle& ot, Point& p, Point& op);
113
+
114
+ Point& NextFlipPoint(Point& ep, Point& eq, Triangle& ot, Point& op);
115
+
116
+ void FlipScanEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle& flip_triangle, Triangle& t, Point& p);
117
+
118
+ void FinalizationPolygon(SweepContext& tcx);
119
+
120
+ std::vector<Node*> nodes_;
121
+
122
+ };
123
+
124
+ }
125
+
126
+ #endif
@@ -0,0 +1,201 @@
1
+ /*
2
+ * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
3
+ * http://code.google.com/p/poly2tri/
4
+ *
5
+ * All rights reserved.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without modification,
8
+ * are permitted provided that the following conditions are met:
9
+ *
10
+ * * Redistributions of source code must retain the above copyright notice,
11
+ * this list of conditions and the following disclaimer.
12
+ * * Redistributions in binary form must reproduce the above copyright notice,
13
+ * this list of conditions and the following disclaimer in the documentation
14
+ * and/or other materials provided with the distribution.
15
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
16
+ * used to endorse or promote products derived from this software without specific
17
+ * prior written permission.
18
+ *
19
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ */
31
+ #include "sweep_context.h"
32
+ #include <algorithm>
33
+ #include "advancing_front.h"
34
+
35
+ namespace p2t {
36
+
37
+ SweepContext::SweepContext(std::vector<Point*> polyline)
38
+ {
39
+ basin = Basin();
40
+ edge_event = EdgeEvent();
41
+
42
+ points_ = polyline;
43
+
44
+ InitEdges(points_);
45
+ }
46
+
47
+ void SweepContext::AddHole(std::vector<Point*> polyline)
48
+ {
49
+ InitEdges(polyline);
50
+ for(int i = 0; i < polyline.size(); i++) {
51
+ points_.push_back(polyline[i]);
52
+ }
53
+ }
54
+
55
+ void SweepContext::AddPoint(Point* point) {
56
+ points_.push_back(point);
57
+ }
58
+
59
+ std::vector<Triangle*> SweepContext::GetTriangles()
60
+ {
61
+ return triangles_;
62
+ }
63
+
64
+ std::list<Triangle*> SweepContext::GetMap()
65
+ {
66
+ return map_;
67
+ }
68
+
69
+ void SweepContext::InitTriangulation()
70
+ {
71
+ double xmax(points_[0]->x), xmin(points_[0]->x);
72
+ double ymax(points_[0]->y), ymin(points_[0]->y);
73
+
74
+ // Calculate bounds.
75
+ for (int i = 0; i < points_.size(); i++) {
76
+ Point& p = *points_[i];
77
+ if (p.x > xmax)
78
+ xmax = p.x;
79
+ if (p.x < xmin)
80
+ xmin = p.x;
81
+ if (p.y > ymax)
82
+ ymax = p.y;
83
+ if (p.y < ymin)
84
+ ymin = p.y;
85
+ }
86
+
87
+ double dx = kAlpha * (xmax - xmin);
88
+ double dy = kAlpha * (ymax - ymin);
89
+ head_ = new Point(xmax + dx, ymin - dy);
90
+ tail_ = new Point(xmin - dx, ymin - dy);
91
+
92
+ // Sort points along y-axis
93
+ std::sort(points_.begin(), points_.end(), cmp);
94
+
95
+ }
96
+
97
+ void SweepContext::InitEdges(std::vector<Point*> polyline)
98
+ {
99
+ int num_points = polyline.size();
100
+ for (int i = 0; i < num_points; i++) {
101
+ int j = i < num_points - 1 ? i + 1 : 0;
102
+ edge_list.push_back(new Edge(*polyline[i], *polyline[j]));
103
+ }
104
+ }
105
+
106
+ Point* SweepContext::GetPoint(const int& index)
107
+ {
108
+ return points_[index];
109
+ }
110
+
111
+ void SweepContext::AddToMap(Triangle* triangle)
112
+ {
113
+ map_.push_back(triangle);
114
+ }
115
+
116
+ Node& SweepContext::LocateNode(Point& point)
117
+ {
118
+ // TODO implement search tree
119
+ return *front_->LocateNode(point.x);
120
+ }
121
+
122
+ void SweepContext::CreateAdvancingFront(std::vector<Node*> nodes)
123
+ {
124
+
125
+ // Initial triangle
126
+ Triangle* triangle = new Triangle(*points_[0], *tail_, *head_);
127
+
128
+ map_.push_back(triangle);
129
+
130
+ af_head_ = new Node(*triangle->GetPoint(1), *triangle);
131
+ af_middle_ = new Node(*triangle->GetPoint(0), *triangle);
132
+ af_tail_ = new Node(*triangle->GetPoint(2));
133
+ front_ = new AdvancingFront(*af_head_, *af_tail_);
134
+
135
+ // TODO: More intuitive if head is middles next and not previous?
136
+ // so swap head and tail
137
+ af_head_->next = af_middle_;
138
+ af_middle_->next = af_tail_;
139
+ af_middle_->prev = af_head_;
140
+ af_tail_->prev = af_middle_;
141
+ }
142
+
143
+ void SweepContext::RemoveNode(Node* node)
144
+ {
145
+ delete node;
146
+ }
147
+
148
+ void SweepContext::MapTriangleToNodes(Triangle& t)
149
+ {
150
+ for (int i = 0; i < 3; i++) {
151
+ if (!t.GetNeighbor(i)) {
152
+ Node* n = front_->LocatePoint(t.PointCW(*t.GetPoint(i)));
153
+ if (n)
154
+ n->triangle = &t;
155
+ }
156
+ }
157
+ }
158
+
159
+ void SweepContext::RemoveFromMap(Triangle* triangle)
160
+ {
161
+ map_.remove(triangle);
162
+ }
163
+
164
+ void SweepContext::MeshClean(Triangle& triangle)
165
+ {
166
+ if (&triangle != NULL && !triangle.IsInterior()) {
167
+ triangle.IsInterior(true);
168
+ triangles_.push_back(&triangle);
169
+ for (int i = 0; i < 3; i++) {
170
+ if (!triangle.constrained_edge[i])
171
+ MeshClean(*triangle.GetNeighbor(i));
172
+ }
173
+ }
174
+ }
175
+
176
+ SweepContext::~SweepContext()
177
+ {
178
+
179
+ // Clean up memory
180
+
181
+ delete head_;
182
+ delete tail_;
183
+ delete front_;
184
+ delete af_head_;
185
+ delete af_middle_;
186
+ delete af_tail_;
187
+
188
+ typedef std::list<Triangle*> type_list;
189
+
190
+ for(type_list::iterator iter = map_.begin(); iter != map_.end(); ++iter) {
191
+ Triangle* ptr = *iter;
192
+ delete ptr;
193
+ }
194
+
195
+ for(int i = 0; i < edge_list.size(); i++) {
196
+ delete edge_list[i];
197
+ }
198
+
199
+ }
200
+
201
+ }
@@ -0,0 +1,185 @@
1
+ /*
2
+ * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
3
+ * http://code.google.com/p/poly2tri/
4
+ *
5
+ * All rights reserved.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without modification,
8
+ * are permitted provided that the following conditions are met:
9
+ *
10
+ * * Redistributions of source code must retain the above copyright notice,
11
+ * this list of conditions and the following disclaimer.
12
+ * * Redistributions in binary form must reproduce the above copyright notice,
13
+ * this list of conditions and the following disclaimer in the documentation
14
+ * and/or other materials provided with the distribution.
15
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
16
+ * used to endorse or promote products derived from this software without specific
17
+ * prior written permission.
18
+ *
19
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ */
31
+
32
+ #ifndef SWEEP_CONTEXT_H
33
+ #define SWEEP_CONTEXT_H
34
+
35
+ #include <list>
36
+ #include <vector>
37
+
38
+ namespace p2t {
39
+
40
+ // Inital triangle factor, seed triangle will extend 30% of
41
+ // PointSet width to both left and right.
42
+ const double kAlpha = 0.3;
43
+
44
+ struct Point;
45
+ class Triangle;
46
+ struct Node;
47
+ struct Edge;
48
+ class AdvancingFront;
49
+
50
+ class SweepContext {
51
+ public:
52
+
53
+ /// Constructor
54
+ SweepContext(std::vector<Point*> polyline);
55
+ /// Destructor
56
+ ~SweepContext();
57
+
58
+ void set_head(Point* p1);
59
+
60
+ Point* head();
61
+
62
+ void set_tail(Point* p1);
63
+
64
+ Point* tail();
65
+
66
+ int point_count();
67
+
68
+ Node& LocateNode(Point& point);
69
+
70
+ void RemoveNode(Node* node);
71
+
72
+ void CreateAdvancingFront(std::vector<Node*> nodes);
73
+
74
+ /// Try to map a node to all sides of this triangle that don't have a neighbor
75
+ void MapTriangleToNodes(Triangle& t);
76
+
77
+ void AddToMap(Triangle* triangle);
78
+
79
+ Point* GetPoint(const int& index);
80
+
81
+ Point* GetPoints();
82
+
83
+ void RemoveFromMap(Triangle* triangle);
84
+
85
+ void AddHole(std::vector<Point*> polyline);
86
+
87
+ void AddPoint(Point* point);
88
+
89
+ AdvancingFront* front();
90
+
91
+ void MeshClean(Triangle& triangle);
92
+
93
+ std::vector<Triangle*> GetTriangles();
94
+ std::list<Triangle*> GetMap();
95
+
96
+ std::vector<Edge*> edge_list;
97
+
98
+ struct Basin {
99
+ Node* left_node;
100
+ Node* bottom_node;
101
+ Node* right_node;
102
+ double width;
103
+ bool left_highest;
104
+
105
+ Basin() : left_node(NULL), bottom_node(NULL), right_node(NULL), width(0.0), left_highest(false)
106
+ {
107
+ }
108
+
109
+ void Clear()
110
+ {
111
+ left_node = NULL;
112
+ bottom_node = NULL;
113
+ right_node = NULL;
114
+ width = 0.0;
115
+ left_highest = false;
116
+ }
117
+ };
118
+
119
+ struct EdgeEvent {
120
+ Edge* constrained_edge;
121
+ bool right;
122
+
123
+ EdgeEvent() : constrained_edge(NULL), right(false)
124
+ {
125
+ }
126
+ };
127
+
128
+ Basin basin;
129
+ EdgeEvent edge_event;
130
+
131
+ private:
132
+
133
+ friend class Sweep;
134
+
135
+ std::vector<Triangle*> triangles_;
136
+ std::list<Triangle*> map_;
137
+ std::vector<Point*> points_;
138
+
139
+ // Advancing front
140
+ AdvancingFront* front_;
141
+ // head point used with advancing front
142
+ Point* head_;
143
+ // tail point used with advancing front
144
+ Point* tail_;
145
+
146
+ Node *af_head_, *af_middle_, *af_tail_;
147
+
148
+ void InitTriangulation();
149
+ void InitEdges(std::vector<Point*> polyline);
150
+
151
+ };
152
+
153
+ inline AdvancingFront* SweepContext::front()
154
+ {
155
+ return front_;
156
+ }
157
+
158
+ inline int SweepContext::point_count()
159
+ {
160
+ return points_.size();
161
+ }
162
+
163
+ inline void SweepContext::set_head(Point* p1)
164
+ {
165
+ head_ = p1;
166
+ }
167
+
168
+ inline Point* SweepContext::head()
169
+ {
170
+ return head_;
171
+ }
172
+
173
+ inline void SweepContext::set_tail(Point* p1)
174
+ {
175
+ tail_ = p1;
176
+ }
177
+
178
+ inline Point* SweepContext::tail()
179
+ {
180
+ return tail_;
181
+ }
182
+
183
+ }
184
+
185
+ #endif