Exemplo n.º 1
0
        /// <summary>
        /// Gets the Voronoi diagram as raw output data.
        /// </summary>
        /// <param name="mesh"></param>
        /// <returns></returns>
        /// <remarks>
        /// The Voronoi diagram is the geometric dual of the Delaunay triangulation.
        /// Hence, the Voronoi vertices are listed by traversing the Delaunay
        /// triangles, and the Voronoi edges are listed by traversing the Delaunay
        /// edges.
        ///</remarks>
        private void Generate()
        {
            _TriangleNetMesh.Renumber();
            _TriangleNetMesh.MakeVertexMap();

            // Allocate space for voronoi diagram
            points  = new Point[_TriangleNetMesh.triangles.Count + _TriangleNetMesh.hullsize];
            regions = new Dictionary <int, VoronoiRegion>(_TriangleNetMesh.vertices.Count);

            rayPoints = new Dictionary <int, Point>();
            rayIndex  = 0;

            bounds = new Rectangle();

            // Compute triangles circumcenters and setup bounding box
            ComputeCircumCenters();

            // Add all Voronoi regions to the map.
            foreach (var vertex in _TriangleNetMesh.vertices.Values)
            {
                regions.Add(vertex.id, new VoronoiRegion(vertex));
            }

            // Loop over the mesh vertices (Voronoi generators).
            foreach (var region in regions.Values)
            {
                //if (item.Boundary == 0)
                {
                    ConstructCell(region);
                }
            }
        }
        /// <summary>
        /// Computes the bounded voronoi diagram.
        /// </summary>
        private void Generate()
        {
            _TriangleNetMesh.Renumber();
            _TriangleNetMesh.MakeVertexMap();

            // Allocate space for voronoi diagram
            regions = new List <VoronoiRegion>(_TriangleNetMesh.vertices.Count);

            points    = new Point[_TriangleNetMesh.triangles.Count];
            segPoints = new List <Point>(_TriangleNetMesh.subsegs.Count * 4);

            ComputeCircumCenters();

            TagBlindTriangles();

            foreach (var v in _TriangleNetMesh.vertices.Values)
            {
                // TODO: Need a reliable way to check if a vertex is on a segment
                if (v.type == VertexType.FreeVertex || v.label == 0)
                {
                    ConstructCell(v);
                }
                else if (includeBoundary)
                {
                    ConstructBoundaryCell(v);
                }
            }

            // Add the new points on segments to the point array.
            int length = points.Length;

            Array.Resize <Point>(ref points, length + segPoints.Count);

            for (int i = 0; i < segPoints.Count; i++)
            {
                points[length + i] = segPoints[i];
            }

            segPoints.Clear();
            segPoints = null;
        }
 public VertexCirculator(TriangleNetMesh triangleNetMesh)
 {
     triangleNetMesh.MakeVertexMap();
 }
Exemplo n.º 4
0
        /// <summary>
        /// Test the mesh for topological consistency.
        /// </summary>
        public static bool IsConsistent(TriangleNetMesh triangleNetMesh)
        {
            Otri   tri = default(Otri);
            Otri   oppotri = default(Otri), oppooppotri = default(Otri);
            Vertex org, dest, apex;
            Vertex oppoorg, oppodest;

            var logger = Log.Instance;

            // Temporarily turn on exact arithmetic if it's off.
            bool saveexact = Behavior.NoExact;

            Behavior.NoExact = false;

            int horrors = 0;

            // Run through the list of triangles, checking each one.
            foreach (var t in triangleNetMesh.triangles)
            {
                tri.tri = t;

                // Check all three edges of the triangle.
                for (tri.orient = 0; tri.orient < 3; tri.orient++)
                {
                    org  = tri.Org();
                    dest = tri.Dest();
                    if (tri.orient == 0)
                    {
                        // Only test for inversion once.
                        // Test if the triangle is flat or inverted.
                        apex = tri.Apex();
                        if (predicates.CounterClockwise(org, dest, apex) <= 0.0)
                        {
                            if (Log.Verbose)
                            {
                                logger.Warning(String.Format("Triangle is flat or inverted (ID {0}).", t.id),
                                               "MeshValidator.IsConsistent()");
                            }

                            horrors++;
                        }
                    }

                    // Find the neighboring triangle on this edge.
                    tri.Sym(ref oppotri);
                    if (oppotri.tri.id != TriangleNetMesh.DUMMY)
                    {
                        // Check that the triangle's neighbor knows it's a neighbor.
                        oppotri.Sym(ref oppooppotri);
                        if ((tri.tri != oppooppotri.tri) || (tri.orient != oppooppotri.orient))
                        {
                            if (tri.tri == oppooppotri.tri && Log.Verbose)
                            {
                                logger.Warning("Asymmetric triangle-triangle bond: (Right triangle, wrong orientation)",
                                               "MeshValidator.IsConsistent()");
                            }

                            horrors++;
                        }
                        // Check that both triangles agree on the identities
                        // of their shared vertices.
                        oppoorg  = oppotri.Org();
                        oppodest = oppotri.Dest();
                        if ((org != oppodest) || (dest != oppoorg))
                        {
                            if (Log.Verbose)
                            {
                                logger.Warning("Mismatched edge coordinates between two triangles.",
                                               "MeshValidator.IsConsistent()");
                            }

                            horrors++;
                        }
                    }
                }
            }

            // Check for unconnected vertices
            triangleNetMesh.MakeVertexMap();
            foreach (var v in triangleNetMesh.vertices.Values)
            {
                if (v.tri.tri == null && Log.Verbose)
                {
                    logger.Warning("Vertex (ID " + v.id + ") not connected to mesh (duplicate input vertex?)",
                                   "MeshValidator.IsConsistent()");
                }
            }

            // Restore the status of exact arithmetic.
            Behavior.NoExact = saveexact;

            return(horrors == 0);
        }