QXRD  0.11.16
Classes | Functions
triangulate.h File Reference

(Commit a65ccc9... : jennings : 2016-03-15 14:00:18 -0500)

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  ITRIANGLE
 
struct  IEDGE
 
struct  XYZ
 

Functions

int Triangulate (int nv, XYZ *pxyz, ITRIANGLE *v, int *ntri)
 

Function Documentation

int Triangulate ( int  nv,
XYZ pxyz,
ITRIANGLE v,
int *  ntri 
)

Definition at line 41 of file triangulate.c.

References CircumCircle(), FALSE, ITRIANGLE::p1, IEDGE::p1, ITRIANGLE::p2, IEDGE::p2, ITRIANGLE::p3, TRUE, XYZ::x, XYZ::y, and XYZ::z.

Referenced by QxrdCenterFinder::calculateCalibration().

42 {
43  int *complete = NULL;
44  IEDGE *edges = NULL;
45  int nedge = 0;
46  int trimax,emax = 200;
47  int status = 0;
48 
49  int inside;
50  int i,j,k;
51  double xp,yp,x1,y1,x2,y2,x3,y3,xc,yc,r;
52  double xmin,xmax,ymin,ymax,xmid,ymid;
53  double dx,dy,dmax;
54 
55  /* Allocate memory for the completeness list, flag for each triangle */
56  trimax = 4 * nv;
57  if ((complete = malloc(trimax*sizeof(int))) == NULL) {
58  status = 1;
59  goto skip;
60  }
61 
62  /* Allocate memory for the edge list */
63  if ((edges = malloc(emax*(long)sizeof(IEDGE))) == NULL) {
64  status = 2;
65  goto skip;
66  }
67 
68  /*
69  Find the maximum and minimum vertex bounds.
70  This is to allow calculation of the bounding triangle
71  */
72  xmin = pxyz[0].x;
73  ymin = pxyz[0].y;
74  xmax = xmin;
75  ymax = ymin;
76  for (i=1;i<nv;i++) {
77  if (pxyz[i].x < xmin) xmin = pxyz[i].x;
78  if (pxyz[i].x > xmax) xmax = pxyz[i].x;
79  if (pxyz[i].y < ymin) ymin = pxyz[i].y;
80  if (pxyz[i].y > ymax) ymax = pxyz[i].y;
81  }
82  dx = xmax - xmin;
83  dy = ymax - ymin;
84  dmax = (dx > dy) ? dx : dy;
85  xmid = (xmax + xmin) / 2.0;
86  ymid = (ymax + ymin) / 2.0;
87 
88  /*
89  Set up the supertriangle
90  This is a triangle which encompasses all the sample points.
91  The supertriangle coordinates are added to the end of the
92  vertex list. The supertriangle is the first triangle in
93  the triangle list.
94  */
95  pxyz[nv+0].x = xmid - 20 * dmax;
96  pxyz[nv+0].y = ymid - dmax;
97  pxyz[nv+0].z = 0.0;
98  pxyz[nv+1].x = xmid;
99  pxyz[nv+1].y = ymid + 20 * dmax;
100  pxyz[nv+1].z = 0.0;
101  pxyz[nv+2].x = xmid + 20 * dmax;
102  pxyz[nv+2].y = ymid - dmax;
103  pxyz[nv+2].z = 0.0;
104  v[0].p1 = nv;
105  v[0].p2 = nv+1;
106  v[0].p3 = nv+2;
107  complete[0] = FALSE;
108  *ntri = 1;
109 
110  /*
111  Include each point one at a time into the existing mesh
112  */
113  for (i=0;i<nv;i++) {
114 
115  xp = pxyz[i].x;
116  yp = pxyz[i].y;
117  nedge = 0;
118 
119  /*
120  Set up the edge buffer.
121  If the point (xp,yp) lies inside the circumcircle then the
122  three edges of that triangle are added to the edge buffer
123  and that triangle is removed.
124  */
125  for (j=0;j<(*ntri);j++) {
126  if (complete[j])
127  continue;
128  x1 = pxyz[v[j].p1].x;
129  y1 = pxyz[v[j].p1].y;
130  x2 = pxyz[v[j].p2].x;
131  y2 = pxyz[v[j].p2].y;
132  x3 = pxyz[v[j].p3].x;
133  y3 = pxyz[v[j].p3].y;
134  inside = CircumCircle(xp,yp,x1,y1,x2,y2,x3,y3,&xc,&yc,&r);
135  if (xc < xp && ((xp-xc)*(xp-xc)) > r)
136  complete[j] = TRUE;
137  if (inside) {
138  /* Check that we haven't exceeded the edge list size */
139  if (nedge+3 >= emax) {
140  emax += 100;
141  if ((edges = realloc(edges,emax*(long)sizeof(IEDGE))) == NULL) {
142  status = 3;
143  goto skip;
144  }
145  }
146  edges[nedge+0].p1 = v[j].p1;
147  edges[nedge+0].p2 = v[j].p2;
148  edges[nedge+1].p1 = v[j].p2;
149  edges[nedge+1].p2 = v[j].p3;
150  edges[nedge+2].p1 = v[j].p3;
151  edges[nedge+2].p2 = v[j].p1;
152  nedge += 3;
153  v[j] = v[(*ntri)-1];
154  complete[j] = complete[(*ntri)-1];
155  (*ntri)--;
156  j--;
157  }
158  }
159 
160  /*
161  Tag multiple edges
162  Note: if all triangles are specified anticlockwise then all
163  interior edges are opposite pointing in direction.
164  */
165  for (j=0;j<nedge-1;j++) {
166  for (k=j+1;k<nedge;k++) {
167  if ((edges[j].p1 == edges[k].p2) && (edges[j].p2 == edges[k].p1)) {
168  edges[j].p1 = -1;
169  edges[j].p2 = -1;
170  edges[k].p1 = -1;
171  edges[k].p2 = -1;
172  }
173  /* Shouldn't need the following, see note above */
174  if ((edges[j].p1 == edges[k].p1) && (edges[j].p2 == edges[k].p2)) {
175  edges[j].p1 = -1;
176  edges[j].p2 = -1;
177  edges[k].p1 = -1;
178  edges[k].p2 = -1;
179  }
180  }
181  }
182 
183  /*
184  Form new triangles for the current point
185  Skipping over any tagged edges.
186  All edges are arranged in clockwise order.
187  */
188  for (j=0;j<nedge;j++) {
189  if (edges[j].p1 < 0 || edges[j].p2 < 0)
190  continue;
191  if ((*ntri) >= trimax) {
192  status = 4;
193  goto skip;
194  }
195  v[*ntri].p1 = edges[j].p1;
196  v[*ntri].p2 = edges[j].p2;
197  v[*ntri].p3 = i;
198  complete[*ntri] = FALSE;
199  (*ntri)++;
200  }
201  }
202 
203  /*
204  Remove triangles with supertriangle vertices
205  These are triangles which have a vertex number greater than nv
206  */
207  for (i=0;i<(*ntri);i++) {
208  if (v[i].p1 >= nv || v[i].p2 >= nv || v[i].p3 >= nv) {
209  v[i] = v[(*ntri)-1];
210  (*ntri)--;
211  i--;
212  }
213  }
214 
215 skip:
216  free(edges);
217  free(complete);
218  return(status);
219 }
int p2
Definition: triangulate.c:11
#define FALSE
Definition: triangulate.c:3
int CircumCircle(double xp, double yp, double x1, double y1, double x2, double y2, double x3, double y3, double *xc, double *yc, double *rsqr)
Definition: triangulate.c:227
double x
Definition: triangulate.c:14
#define TRUE
Definition: triangulate.c:4
double z
Definition: triangulate.c:14
double y
Definition: triangulate.c:14
int p1
Definition: triangulate.c:11

Here is the call graph for this function:

Here is the caller graph for this function: