NAGASH 0.9.8
Next Generation Analysis System
Loading...
Searching...
No Matches
Graph2DTool.cxx
Go to the documentation of this file.
2#include "Eigen/Dense"
3
4using namespace NAGASH;
5using namespace std;
6using namespace Eigen;
7
9{
10 Matrix3d Bottom;
11 Matrix3d XTop;
12 Matrix3d YTop;
13
14 for (int i = 0; i < 3; i++)
15 {
16 Bottom(i, 0) = P[i].X();
17 Bottom(i, 1) = P[i].Y();
18 Bottom(i, 2) = 1;
19
20 XTop(i, 0) = pow(P[i].X(), 2) + pow(P[i].Y(), 2);
21 XTop(i, 1) = P[i].Y();
22 XTop(i, 2) = 1;
23
24 YTop(i, 0) = P[i].X();
25 YTop(i, 1) = pow(P[i].X(), 2) + pow(P[i].Y(), 2);
26 YTop(i, 2) = 1;
27 }
28
29 Point cent(XTop.determinant() / Bottom.determinant() / 2,
30 YTop.determinant() / Bottom.determinant() / 2);
31
32 double r = cent.Distance(P[0]);
33
34 return Circle(cent, r);
35}
36
38{
39 return (c.Radius() > Distance(c.Center()));
40}
41
43{
44 Point PA(t.Vertex(0).X() - x, t.Vertex(0).Y() - y);
45 Point PB(t.Vertex(1).X() - x, t.Vertex(1).Y() - y);
46 Point PC(t.Vertex(2).X() - x, t.Vertex(2).Y() - y);
47
48 double t1 = PA.X() * PB.Y() - PA.Y() * PB.X();
49 double t2 = PB.X() * PC.Y() - PB.Y() * PC.X();
50 double t3 = PC.X() * PA.Y() - PC.Y() * PA.X();
51
52 return ((t1 * t2 >= 0) && (t1 * t3 >= 0));
53}
54
55Graph2DTool::Graph2DTool(std::shared_ptr<MSGTool> msg, double prec) : Tool(msg)
56{
57 PRECISION = prec;
58}
59
60std::vector<Triangle> Graph2DTool::DelaunayTriangulation(std::vector<Point> p_vec)
61{
62 vector<Triangle> tri_vec;
63 vector<Triangle> temp_tri_vec;
64
65 if (p_vec.size() < 3)
66 {
67 MSGUser()->MSG_ERROR("Need at least 3 points for triangulation!");
68 return tri_vec;
69 }
70
71 vector<int> index_vec;
72
73 for (int i = 0; i < p_vec.size(); i++)
74 index_vec.push_back(i);
75
76 for (int i = 0; i < index_vec.size() - 1; i++)
77 {
78 for (int j = i + 1; j < index_vec.size(); j++)
79 {
80 if (p_vec[index_vec[i]].X() > p_vec[index_vec[j]].X())
81 {
82 int temp = index_vec[i];
83 index_vec[i] = index_vec[j];
84 index_vec[j] = temp;
85 }
86 }
87 }
88
89 double XMax = p_vec[0].X();
90 double XMin = p_vec[0].X();
91 double YMax = p_vec[0].Y();
92 double YMin = p_vec[0].Y();
93
94 for (int i = 1; i < p_vec.size(); i++)
95 {
96 if (p_vec[i].X() > XMax)
97 XMax = p_vec[i].X();
98 if (p_vec[i].X() < XMin)
99 XMin = p_vec[i].X();
100 if (p_vec[i].Y() > YMax)
101 YMax = p_vec[i].Y();
102 if (p_vec[i].Y() < YMin)
103 YMin = p_vec[i].Y();
104 }
105
106 double DX = XMax - XMin;
107 double DY = YMax - YMin;
108
109 Triangle super(Point((XMax + XMin) / 2, YMax + 2 * DY),
110 Point((XMax + XMin) / 2 + 2.5 * DX, YMin - 2 * DY),
111 Point((XMax + XMin) / 2 - 2.5 * DX, YMin - 2 * DY));
112
113 // Check
114 for (int i = 0; i < p_vec.size(); i++)
115 {
116 if (!p_vec[i].IsInside(super))
117 MSGUser()->MSG_ERROR("Point ", i, " is outside the super triangle!");
118 }
119
120 temp_tri_vec.push_back(super);
121
122 for (int i = 0; i < index_vec.size(); i++)
123 {
124 vector<Edge> edg_vec;
125 Point P = p_vec[index_vec[i]];
126 for (int j = 0; j < temp_tri_vec.size(); j++)
127 {
128 Circle outcir = temp_tri_vec[j].CircumscribedCircle();
129
130 if (P.X() > (outcir.Center().X() + outcir.Radius()))
131 {
132 tri_vec.push_back(temp_tri_vec[j]);
133 temp_tri_vec.erase(temp_tri_vec.begin() + j);
134 j--;
135 continue;
136 }
137 else if (P.IsInside(outcir))
138 {
139 edg_vec.push_back(Edge(temp_tri_vec[j].Vertex(0), temp_tri_vec[j].Vertex(1)));
140 edg_vec.push_back(Edge(temp_tri_vec[j].Vertex(1), temp_tri_vec[j].Vertex(2)));
141 edg_vec.push_back(Edge(temp_tri_vec[j].Vertex(0), temp_tri_vec[j].Vertex(2)));
142
143 temp_tri_vec.erase(temp_tri_vec.begin() + j);
144 j--;
145 continue;
146 }
147 else
148 {
149 continue;
150 }
151 }
152
153 if (edg_vec.size() > 1)
154 {
155 for (int j = 0; j < edg_vec.size() - 1; j++)
156 {
157 for (int k = j + 1; k < edg_vec.size(); k++)
158 {
159 if ((edg_vec[j].Start().Distance(edg_vec[k].Start()) < PRECISION) &&
160 (edg_vec[j].End().Distance(edg_vec[k].End()) < PRECISION))
161 {
162 edg_vec.erase(edg_vec.begin() + k);
163 k--;
164 continue;
165 }
166 if ((edg_vec[j].Start().Distance(edg_vec[k].End()) < PRECISION) &&
167 (edg_vec[j].End().Distance(edg_vec[k].Start()) < PRECISION))
168 {
169 edg_vec.erase(edg_vec.begin() + k);
170 k--;
171 continue;
172 }
173 }
174 }
175 }
176
177 if (edg_vec.size() > 0)
178 {
179 for (int j = 0; j < edg_vec.size(); j++)
180 temp_tri_vec.push_back(Triangle(edg_vec[j], P));
181 }
182 }
183
184 tri_vec.insert(tri_vec.end(), temp_tri_vec.begin(), temp_tri_vec.end());
185
186 for (int i = 0; i < tri_vec.size(); i++)
187 {
188 bool toremove = false;
189 for (int j = 0; j < 3; j++)
190 {
191 for (int k = 0; k < 3; k++)
192 {
193 if (tri_vec[i].Vertex(j).Distance(super.Vertex(k)) < PRECISION)
194 toremove = true;
195 }
196 }
197 for (int j = 0; j < p_vec.size(); j++)
198 {
199 bool isOnEdge = false;
200 for (int k = 0; k < 3; k++)
201 {
202 if (p_vec[j].Distance(tri_vec[i].Vertex(k)) < PRECISION)
203 isOnEdge = true;
204 }
205 if (isOnEdge)
206 continue;
207 if (p_vec[j].IsInside(tri_vec[i].CircumscribedCircle()))
208 toremove = true;
209 }
210 if (toremove)
211 {
212 tri_vec.erase(tri_vec.begin() + i);
213 i--;
214 }
215 }
216
217 return tri_vec;
218}
double Radius()
Definition Graph2DTool.h:67
Graph2DTool(std::shared_ptr< MSGTool > msg, double prec=1e-5)
std::vector< Triangle > DelaunayTriangulation(std::vector< Point > p_vec)
double Distance(Point a)
Definition Graph2DTool.h:31
bool IsInside(Circle c)
Provide interface for all tools in NAGASH.
Definition Tool.h:72
std::shared_ptr< MSGTool > MSGUser()
return the MSGTool inside.
Definition Tool.h:91
Point Vertex(int index)
Definition Graph2DTool.h:90
Circle CircumscribedCircle()