Exemple #1
0
        public static Voronoi FromDelaunay(Adjacency adjacency)
        {
            Voronoi v = new Voronoi();

            int[] triangleRemapping = new int[adjacency.triangles.Count];

            for (int i = 0; i < adjacency.triangles.Count; i++)
            {
                Adjacency.Triangle t = adjacency.triangles[i];
                if (!t.valid)
                {
                    triangleRemapping[i] = -1;
                    continue;
                }
                Vertex c; float r;
                t.CircumCircle(adjacency.vertices, out c, out r);

                triangleRemapping[i] = v.vertices.Count;
                v.vertices.Add(c);
            }
            for (int i = 0; i < adjacency.triangles.Count; i++)
            {
                Adjacency.Triangle t = adjacency.triangles[i];
                if (!t.valid)
                {
                    continue;
                }
                for (int e = 0; e < 3; e++)
                {
                    int adjT = adjacency.AdjacentTriangle(i, e);
                    if (adjT < 0 || adjacency.triangles[adjT].valid == false)
                    {
                        continue;
                    }
                    if (triangleRemapping[adjT] < 0)
                    {
                        continue;                              // already processed
                    }
                    int voronoiV0 = triangleRemapping[i];
                    int voronoiV1 = triangleRemapping[adjT];
                    Debug.Assert(voronoiV0 >= 0 && voronoiV1 >= 0);

                    // the 2 vertices shared by the adjacent triangles will become
                    // the voronoi cells divided by the edge we're creating
                    int cellA = adjacency.edges[Math.Abs(t.edges[e]) - 1].vertices[0];
                    int cellB = adjacency.edges[Math.Abs(t.edges[e]) - 1].vertices[1];

                    v.edges.Add(new Edge(voronoiV0, voronoiV1, cellA, cellB));
                }
                triangleRemapping[i] = -1;
            }
            return(v);
        }
Exemple #2
0
        private static bool Delaunay2DInsertPoints(List <Vertex> vertices, Adjacency adjacency)
        {
            // Insert points

            HashSet <int> toCheck = new HashSet <int>();

            for (int i = 0; i < vertices.Count; i++)
            {
                // Insert Vi
                Vertex Vi = vertices[i];

                bool skip = false;
                for (int j = 0; j < adjacency.vertices.Count; j++)
                {
                    if ((Vi - adjacency.vertices[j]).Length() <= COINCIDENT_POINTS_DISTANCE_EPSILON)
                    {
                        // the point has already been inserted. Skip it
                        skip = true;
                        break;
                    }
                }
                if (skip)
                {
                    continue;
                }

                if (OnDelaunayInsertPoint != null)
                {
                    OnDelaunayInsertPoint(adjacency, Vi);
                }

                int tri = adjacency.PointInTriangle(Vi);

                if (tri < 0)
                {
                    Debug.Assert(false);
                    return(false);
                }

                // check whether the point lies exactly on one edge of the triangle
                int edgeIdx = adjacency.PointInTriangleEdge(Vi, tri);
                if (edgeIdx >= 0)
                {
                    // split the edge by Vi
                    int[] result;
                    adjacency.SplitEdge(edgeIdx, Vi, out result);
                    for (int j = 0; j < 4; j++)
                    {
                        if (result[j] >= 0)
                        {
                            toCheck.Add(result[j]);
                        }
                    }
                }
                else
                {
                    // split the triangle in 3
                    int[] result;
                    adjacency.SplitTriangle(tri, Vi, out result);
                    for (int j = 0; j < 3; j++)
                    {
                        toCheck.Add(result[j]);
                    }
                }

                while (toCheck.Count > 0)
                {
                    int t = toCheck.Last <int>();
                    toCheck.Remove(t);

                    Adjacency.Triangle triangle = adjacency.triangles[t];
                    if (!triangle.valid)
                    {
                        continue;
                    }

                    if (OnDelaunayTriangleCheck != null)
                    {
                        OnDelaunayTriangleCheck(adjacency, t);
                    }

                    // check Delaunay condition
                    for (int e = 0; e < 3; e++)
                    {
                        if (!adjacency.triangles[t].valid)
                        {
                            continue;
                        }

                        int adjacentIdx = adjacency.AdjacentTriangle(t, e);
                        if (adjacentIdx < 0)
                        {
                            continue;
                        }
                        int globalEdgeIndex         = Math.Abs(triangle.edges[e]) - 1;
                        Adjacency.Triangle adjacent = adjacency.triangles[adjacentIdx];
                        if (!adjacent.valid)
                        {
                            continue;
                        }
                        Debug.Assert(adjacent.valid);
                        int edgeFromAdjacent = adjacent.LocalEdgeIndex(globalEdgeIndex);
                        Debug.Assert(edgeFromAdjacent >= 0);
                        int v = adjacency.VertexOutOfTriEdge(adjacentIdx, edgeFromAdjacent);
                        Debug.Assert(v >= 0);
                        Debug.Assert(!triangle.Contains(v));

                        if (triangle.InsideCircumcircle(adjacency.vertices[v], adjacency.vertices) > INSIDE_CIRCUMCIRCLE_EPSILON)
                        {
                            int[] result;
                            if (adjacency.FlipTriangles(t, adjacentIdx, out result))
                            {
                                toCheck.Add(result[0]);
                                toCheck.Add(result[1]);
                                //break;
                            }
                        }
                    }
                }

                if (OnDelaunayStep != null)
                {
                    OnDelaunayStep(adjacency);
                }
            }
            return(true);
        }
Exemple #3
0
        private static void Delaunay2DRemoveSuperTriangle(Adjacency adjacency, int stIdx1, int stIdx2, int stIdx3, out List <int> outTriangles, List <Vertex> vertices)
        {
            outTriangles = new List <int>();
            // remove triangles containing vertices from the supertriangle
            for (int i = 0; i < adjacency.triangles.Count; i++)
            {
                Adjacency.Triangle triangle = adjacency.triangles[i];
                if (!triangle.valid)
                {
                    continue;
                }
                if (triangle.Contains(stIdx1) || triangle.Contains(stIdx2) || triangle.Contains(stIdx3))
                {
                    adjacency.RemoveTriangle(i);
                }
                else
                {
                    for (int j = 0; j < 3; j++)
                    {
                        Debug.Assert(triangle.vertices[j] >= 0 && triangle.vertices[j] < adjacency.vertices.Count);
                        outTriangles.Add(triangle.vertices[j]);
                    }
                }
            }
            adjacency.invalidTriangles.Clear();

            // remove first 3 vertices (belonging to the supertriangle) and remap all remaining tris

            for (int i = 0; i < outTriangles.Count; i++)
            {
                outTriangles[i] -= 3;
            }

            int numTris = adjacency.triangles.Count;

            for (int i = 0; i < numTris; i++)
            {
                if (!adjacency.triangles[i].valid)
                {
                    int remappedTriangle = numTris - 1;
                    if (remappedTriangle > i)
                    {
                        adjacency.triangles[i] = adjacency.triangles[remappedTriangle];
                        numTris--;

                        // remap edges pointing to this triangle
                        for (int e = 0; e < 3; e++)
                        {
                            int edgeIndex = Math.Abs(adjacency.triangles[i].edges[e]) - 1;
                            if (adjacency.edges[edgeIndex].triangles[0] == remappedTriangle)
                            {
                                adjacency.edges[edgeIndex].triangles[0] = i;
                            }
                            if (adjacency.edges[edgeIndex].triangles[1] == remappedTriangle)
                            {
                                adjacency.edges[edgeIndex].triangles[1] = i;
                            }
                        }
#if  false
                        for (int e = 0; e < adjacency.edges.Count; e++)
                        {
                            Adjacency.Edge edge = adjacency.edges[e];
                            for (int et = 0; et < 2; et++)
                            {
                                Debug.Assert(edge.triangles[et] != i);
                                if (edge.triangles[et] == remappedTriangle)
                                {
                                    edge.triangles[et] = i;
                                }
                            }
                        }
#endif

                        i--;
                    }
                }
                else
                {
                    Adjacency.Triangle t = adjacency.triangles[i];
                    t.vertices[0] -= 3;
                    t.vertices[1] -= 3;
                    t.vertices[2] -= 3;
                }
            }
            adjacency.triangles.RemoveRange(numTris, adjacency.triangles.Count - numTris);
            adjacency.vertices = vertices;
            for (int i = 0; i < adjacency.edges.Count; i++)
            {
                adjacency.edges[i].vertices[0] -= 3;
                adjacency.edges[i].vertices[1] -= 3;
            }
        }