/// <summary> Process a list of points defining a polygon</summary> /// <param name="contour">The list of points describing the polygon /// </param> /// <param name="result">The list of points describing the triangles. Groups /// of 3 describe each triangle /// /// </param> /// <returns> True if we succeeded in completing triangulation /// </returns> private bool Process(PointList contour, PointList result) { /* allocate and initialize list of Vertices in polygon */ int n = contour.Size(); if (n < 3) return false; int[] V = new int[n]; /* we want a counter-clockwise polygon in V */ if (0.0f < Area(contour)) { for (int v = 0; v < n; v++) V[v] = v; } else { for (int v = 0; v < n; v++) V[v] = (n - 1) - v; } int nv = n; /* Remove nv-2 Vertices, creating 1 triangle every time */ int count = 2 * nv; /* error detection */ for (int m = 0, v = nv - 1; nv > 2; ) { /* if we loop, it is probably a non-simple polygon */ if (0 >= (count--)) { //** Triangulate: ERROR - probable bad polygon! return false; } /* three consecutive vertices in current polygon, <u,v,w> */ int u = v; if (nv <= u) u = 0; /* previous */ v = u + 1; if (nv <= v) v = 0; /* new v */ int w = v + 1; if (nv <= w) w = 0; /* Next */ if (Snip(contour, u, v, w, nv, V)) { int a, b, c, s, t; /* true names of the vertices */ a = V[u]; b = V[v]; c = V[w]; /* output Triangle */ result.Add(contour.Item(a)); result.Add(contour.Item(b)); result.Add(contour.Item(c)); m++; /* Remove v from remaining polygon */ for (s = v, t = v + 1; t < nv; s++, t++) { V[s] = V[t]; } nv--; /* resest error detection counter */ count = 2 * nv; } } return true; }
/// <summary> Cut a the contour and Add a triangle into V to describe the /// location of the cut /// /// </summary> /// <param name="contour">The list of points defining the polygon /// </param> /// <param name="u">The index of the first point /// </param> /// <param name="v">The index of the second point /// </param> /// <param name="w">The index of the third point /// </param> /// <param name="n">? /// </param> /// <param name="V">The array to populate with indicies of triangles /// </param> /// <returns> True if a triangle was found /// </returns> private bool Snip(PointList contour, int u, int v, int w, int n, int[] V) { int p; float Ax, Ay, Bx, By, Cx, Cy, Px, Py; Ax = contour.Item(V[u]).X; Ay = contour.Item(V[u]).Y; Bx = contour.Item(V[v]).X; By = contour.Item(V[v]).Y; Cx = contour.Item(V[w]).X; Cy = contour.Item(V[w]).Y; if (EPSILON > (((Bx - Ax) * (Cy - Ay)) - ((By - Ay) * (Cx - Ax)))) { return false; } for (p = 0; p < n; p++) { if ((p == u) || (p == v) || (p == w)) { continue; } Px = contour.Item(V[p]).X; Py = contour.Item(V[p]).Y; if (InsideTriangle(Ax, Ay, Bx, By, Cx, Cy, Px, Py)) { return false; } } return true; }
/// <summary> Find the Area of a polygon defined by the series of points /// in the list /// /// </summary> /// <param name="contour">The list of points defined the contour of the polygon /// (Vector2f) /// </param> /// <returns> The Area of the polygon defined /// </returns> private float Area(PointList contour) { int n = contour.Size(); float A = 0.0f; for (int p = n - 1, q = 0; q < n; p = q++) { Point contourP = contour.Item(p); Point contourQ = contour.Item(q); A += contourP.X * contourQ.Y - contourQ.X * contourP.Y; } return A * 0.5f; }