Exemplo n.º 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);
        }
Exemplo n.º 2
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;
        }
Exemplo n.º 3
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;
        }
Exemplo n.º 4
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);
        }