Beispiel #1
0
        private static DTriangle Circumcircle(List <DVertex> vertices, int i, int j, int k)
        {
            float x1       = vertices[i].x,
                  y1       = vertices[i].y,
                  x2       = vertices[j].x,
                  y2       = vertices[j].y,
                  x3       = vertices[k].x,
                  y3       = vertices[k].y,
                  fabsy1y2 = MathUtils.Abs(y1 - y2),
                  fabsy2y3 = MathUtils.Abs(y2 - y3),
                  xc,
                  yc,
                  m1,
                  m2,
                  mx1,
                  mx2,
                  my1,
                  my2;

            /* Check for coincident points */
            //if ( fabsy1y2 < EPSILON &&
            //	 fabsy2y3 < EPSILON )
            //	throw new Exception( "Eek! Coincident points!" );

            if (fabsy1y2 < EPSILON)
            {
                m2  = -((x3 - x2) / (y3 - y2));
                mx2 = (x2 + x3) / 2.0f;
                my2 = (y2 + y3) / 2.0f;
                xc  = (x2 + x1) / 2.0f;
                yc  = m2 * (xc - mx2) + my2;
            }
            else if (fabsy2y3 < EPSILON)
            {
                m1  = -((x2 - x1) / (y2 - y1));
                mx1 = (x1 + x2) / 2.0f;
                my1 = (y1 + y2) / 2.0f;
                xc  = (x3 + x2) / 2.0f;
                yc  = m1 * (xc - mx1) + my1;
            }
            else
            {
                m1  = -((x2 - x1) / (y2 - y1));
                m2  = -((x3 - x2) / (y3 - y2));
                mx1 = (x1 + x2) / 2.0f;
                mx2 = (x2 + x3) / 2.0f;
                my1 = (y1 + y2) / 2.0f;
                my2 = (y2 + y3) / 2.0f;
                xc  = (m1 * mx1 - m2 * mx2 + my2 - my1) / (m1 - m2);
                yc  = (fabsy1y2 > fabsy2y3) ? m1 * (xc - mx1) + my1 : m2 * (xc - mx2) + my2;
            }

            float dx = x2 - xc;
            float dy = y2 - yc;

            DTriangle triangle = new DTriangle(i, j, k, xc, yc, dx * dx + dy * dy);

            return(triangle);
        }
        public CTriangle(DTriangle dtri, OpenTK.Vector3 v1, OpenTK.Vector3 v2, OpenTK.Vector3 v3)
        {
            // Always start with 3 verts
            original_verts = new CVertex[3];

            tex_index = dtri.tex_index;
            flags     = dtri.flags;

            for (int i = 0; i < 3; i++)
            {
                original_verts[i]        = new CVertex();
                original_verts[i].Normal = dtri.normal[i];
                original_verts[i].UV     = dtri.tex_uv[i];
            }

            original_verts[0].Position = v1;
            original_verts[1].Position = v2;
            original_verts[2].Position = v3;
        }
Beispiel #3
0
        public static List <DTriangle> Triangulate(List <DVertex> vertices)
        {
            int n = vertices.Count;

            /* Bail if there aren't enough vertices to form any triangles. */
            if (n < 3)
            {
                return(new List <DTriangle>());
            }

            vertices.Sort();

            /* Next, find the vertices of the supertriangle (which contains all other
             * triangles), and append them onto the end of a (copy of) the vertex
             * array. */
            float[] st = SuperTriangle(vertices);
            vertices.Add(new DVertex(st[0], st[1]));
            vertices.Add(new DVertex(st[2], st[3]));
            vertices.Add(new DVertex(st[4], st[5]));

            /* Initialize the open list (containing the supertriangle and nothing
             * else) and the closed list (which is empty since we havn't processed
             * any triangles yet). */
            List <DTriangle> open = new List <DTriangle> {
                Circumcircle(vertices, n + 0, n + 1, n + 2)
            };
            List <DTriangle> closed = new List <DTriangle>();
            List <int>       edges  = new List <int>();

            /* Incrementally add each vertex to the mesh. */
            for (int i = 0; i < n; i++)
            {
                edges.Clear();

                /* For each open triangle, check to see if the current point is
                 * inside it's circumcircle. If it is, remove the triangle and add
                 * it's edges to an edge list. */
                for (int j = open.Count - 1; j >= 0; j--)
                {
                    /* If this point is to the right of this triangle's circumcircle,
                     * then this triangle should never get checked again. Remove it
                     * from the open list, add it to the closed list, and skip. */
                    DTriangle openTri   = open[j];
                    DVertex   curVertex = vertices[i];
                    float     dx        = curVertex.x - openTri.x;
                    if (dx > 0.0f && dx * dx > openTri.r)
                    {
                        closed.Add(openTri);
                        open.RemoveAt(j);
                        continue;
                    }

                    /* If we're outside the circumcircle, skip this triangle. */
                    float dy = curVertex.y - openTri.y;
                    if (dx * dx + dy * dy - openTri.r > EPSILON)
                    {
                        continue;
                    }

                    /* Remove the triangle and add it's edges to the edge list. */
                    edges.Add(openTri.v0);
                    edges.Add(openTri.v1);
                    edges.Add(openTri.v1);
                    edges.Add(openTri.v2);
                    edges.Add(openTri.v2);
                    edges.Add(openTri.v0);
                    open.RemoveAt(j);
                }

                /* Remove any doubled edges. */
                Dedup(edges);

                /* Add a new triangle for each edge. */
                for (int j = edges.Count; j > 0;)
                {
                    int b = edges[--j];
                    int a = edges[--j];
                    open.Add(Circumcircle(vertices, a, b, i));
                }
            }

            /* Copy any remaining open triangles to the closed list, and then
             * remove any triangles that share a vertex with the supertriangle,
             * building a list of triplets that represent triangles. */
            closed.AddRange(open);
            open.Clear();

            for (int i = closed.Count - 1; i >= 0; i--)
            {
                DTriangle triangle = closed[i];
                if (triangle.v0 < n && triangle.v1 < n && triangle.v2 < n)
                {
                    open.Add(triangle);
                }
            }

            /* Yay, we're done! */
            return(open);
        }