COVISE Core
Triangulate.h
Go to the documentation of this file.
1 /* This file is part of COVISE.
2 
3  You can use it under the terms of the GNU Lesser General Public License
4  version 2.1 or later, see lgpl-2.1.txt.
5 
6  * License: LGPL 2+ */
7 
8 #ifndef COVISE_TRIANGULATE_H
9 #define COVISE_TRIANGULATE_H
10 
11 #include <vector>
12 
13 static const float EPSILON = 0.0000000001f;
14 
15 typedef struct
16 {
17  float x;
18  float y;
19  int index;
20 } tr_vertex;
21 
22 typedef std::vector<tr_vertex> tr_vertexVector;
23 
24 typedef std::vector<int> tr_intVector;
25 
27 {
28 public:
29  // triangulate a contour/polygon, places results in STL vector
30  // as series of triangles.
31  static bool Process(const tr_vertexVector &contour,
33  {
34  /* allocate and initialize list of Vertices in polygon */
35 
36  int n = (int)contour.size();
37  if (n < 3)
38  return false;
39 
40  int *V = new int[n];
41 
42  /* we want a counter-clockwise polygon in V */
43 
44  if (0.0f < Area(contour))
45  for (int v = 0; v < n; v++)
46  V[v] = v;
47  else
48  for (int v = 0; v < n; v++)
49  V[v] = (n - 1) - v;
50 
51  int nv = n;
52 
53  /* remove nv-2 Vertices, creating 1 triangle every time */
54  int count = 2 * nv; /* error detection */
55 
56  for (int m = 0, v = nv - 1; nv > 2;)
57  {
58  /* if we loop, it is probably a non-simple polygon */
59  if (0 >= (count--))
60  {
61  //** Triangulate: ERROR - probable bad polygon!
62  return false;
63  }
64 
65  /* three consecutive vertices in current polygon, <u,v,w> */
66  int u = v;
67  if (nv <= u)
68  u = 0; /* previous */
69  v = u + 1;
70  if (nv <= v)
71  v = 0; /* new v */
72  int w = v + 1;
73  if (nv <= w)
74  w = 0; /* next */
75 
76  if (Snip(contour, u, v, w, nv, V))
77  {
78  int a, b, c, s, t;
79 
80  /* true names of the vertices */
81  a = V[u];
82  b = V[v];
83  c = V[w];
84 
85  /* output Triangle */
86  result.push_back(contour[a].index);
87  result.push_back(contour[b].index);
88  result.push_back(contour[c].index);
89 
90  m++;
91 
92  /* remove v from remaining polygon */
93  for (s = v, t = v + 1; t < nv; s++, t++)
94  V[s] = V[t];
95  nv--;
96 
97  /* resest error detection counter */
98  count = 2 * nv;
99  }
100  }
101 
102  delete[] V;
103 
104  return true;
105  };
106 
107  // compute area of a contour/polygon
108  static float Area(const tr_vertexVector &contour)
109  {
110 
111  int n = (int)contour.size();
112 
113  float A = 0.0f;
114 
115  for (int p = n - 1, q = 0; q < n; p = q++)
116  {
117  A += contour[p].x * contour[q].y - contour[q].x * contour[p].y;
118  }
119  return A * 0.5f;
120  };
121 
122  // decide if point Px/Py is inside triangle defined by
123  // (Ax,Ay) (Bx,By) (Cx,Cy)
124  static bool InsideTriangle(float Ax, float Ay,
125  float Bx, float By,
126  float Cx, float Cy,
127  float Px, float Py)
128  {
129  float ax, ay, bx, by, cx, cy, apx, apy, bpx, bpy, cpx, cpy;
130  float cCROSSap, bCROSScp, aCROSSbp;
131 
132  ax = Cx - Bx;
133  ay = Cy - By;
134  bx = Ax - Cx;
135  by = Ay - Cy;
136  cx = Bx - Ax;
137  cy = By - Ay;
138  apx = Px - Ax;
139  apy = Py - Ay;
140  bpx = Px - Bx;
141  bpy = Py - By;
142  cpx = Px - Cx;
143  cpy = Py - Cy;
144 
145  aCROSSbp = ax * bpy - ay * bpx;
146  cCROSSap = cx * apy - cy * apx;
147  bCROSScp = bx * cpy - by * cpx;
148 
149  return ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f));
150  };
151 
152 private:
153  static bool Snip(const tr_vertexVector &contour, int u, int v, int w, int n, int *V)
154  {
155  int p;
156  float Ax, Ay, Bx, By, Cx, Cy, Px, Py;
157 
158  Ax = contour[V[u]].x;
159  Ay = contour[V[u]].y;
160 
161  Bx = contour[V[v]].x;
162  By = contour[V[v]].y;
163 
164  Cx = contour[V[w]].x;
165  Cy = contour[V[w]].y;
166 
167  if (EPSILON > (((Bx - Ax) * (Cy - Ay)) - ((By - Ay) * (Cx - Ax))))
168  return false;
169 
170  for (p = 0; p < n; p++)
171  {
172  if ((p == u) || (p == v) || (p == w))
173  continue;
174  Px = contour[V[p]].x;
175  Py = contour[V[p]].y;
176  if (InsideTriangle(Ax, Ay, Bx, By, Cx, Cy, Px, Py))
177  return false;
178  }
179 
180  return true;
181  };
182 };
183 
184 #endif
static float Area(const tr_vertexVector &contour)
Definition: Triangulate.h:108
GLdouble GLdouble t
Definition: khronos-glext.h:6449
GLbyte by
Definition: khronos-glext.h:9725
const GLubyte * c
Definition: khronos-glext.h:9864
Definition: Triangulate.h:26
float y
Definition: Triangulate.h:18
GLdouble s
Definition: khronos-glext.h:6441
GLuint GLuint GLsizei count
Definition: khronos-glext.h:6343
const GLfloat * m
Definition: khronos-glext.h:12117
Definition: Triangulate.h:15
static bool InsideTriangle(float Ax, float Ay, float Bx, float By, float Cx, float Cy, float Px, float Py)
Definition: Triangulate.h:124
GLubyte GLubyte GLubyte GLubyte w
Definition: khronos-glext.h:6793
GLdouble GLdouble GLdouble GLdouble q
Definition: khronos-glext.h:6465
GLuint64EXT * result
Definition: khronos-glext.h:12573
static const float EPSILON
Definition: Triangulate.h:13
GLdouble n
Definition: khronos-glext.h:8447
GLuint index
Definition: khronos-glext.h:6722
float x
Definition: Triangulate.h:17
std::vector< int > tr_intVector
Definition: Triangulate.h:24
std::vector< tr_vertex > tr_vertexVector
Definition: Triangulate.h:22
const GLdouble * v
Definition: khronos-glext.h:6442
GLfloat GLfloat p
Definition: khronos-glext.h:9861
static bool Process(const tr_vertexVector &contour, tr_intVector &result)
Definition: Triangulate.h:31
GLboolean GLboolean GLboolean GLboolean a
Definition: khronos-glext.h:6895
static bool Snip(const tr_vertexVector &contour, int u, int v, int w, int n, int *V)
Definition: Triangulate.h:153
GLfloat f
Definition: khronos-glext.h:8258
GLboolean GLboolean GLboolean b
Definition: khronos-glext.h:6895
int index
Definition: Triangulate.h:19