예제 #1
0
        /// <summary>
        /// Creates a Voronoi DCEL from a triangulation. Triangulation should be Delaunay
        /// </summary>
        /// <param name="m_Delaunay"></param>
        /// <returns></returns>
        public static DCEL Create(Triangulation m_Delaunay)
        {
            if (!Delaunay.IsValid(m_Delaunay))
            {
                throw new GeomException("Triangulation should be delaunay for the Voronoi diagram.");
            }

            var dcel = new DCEL();

            // create vertices for each triangles circumcenter and store them in a dictionary
            Dictionary <Triangle, DCELVertex> vertexMap = new Dictionary <Triangle, DCELVertex>();

            foreach (var triangle in m_Delaunay.Triangles)
            {
                // degenerate triangle, just ignore
                if (!triangle.Circumcenter.HasValue)
                {
                    continue;
                }

                var vertex = new DCELVertex(triangle.Circumcenter.Value);
                dcel.AddVertex(vertex);
                vertexMap.Add(triangle, vertex);
            }

            // remember which edges where visited
            // since each edge has a twin
            var edgesVisited = new HashSet <TriangleEdge>();

            foreach (var edge in m_Delaunay.Edges)
            {
                // either already visited twin edge or edge is outer triangle
                if (edgesVisited.Contains(edge) || edge.IsOuter)
                {
                    continue;
                }

                // add edge between the two adjacent triangles vertices
                // vertices at circumcenter of triangle
                if (edge.T != null && edge.Twin.T != null)
                {
                    var v1 = vertexMap[edge.T];
                    var v2 = vertexMap[edge.Twin.T];

                    HalfEdge e1 = dcel.AddEdge(v1, v2);

                    e1.Twin.Face.owner = m_Delaunay.GetOwner(edge.Point1);
                    e1.Face.owner      = m_Delaunay.GetOwner(edge.Point2);

                    edgesVisited.Add(edge);
                    edgesVisited.Add(edge.Twin);
                }
            }

            return(dcel);
        }