Ejemplo n.º 1
0
        /// <summary>
        /// True if <paramref name="pos"/> inside the convex hull formed by the triangulation.
        /// </summary>
        /// <param name="pos">The position to test</param>
        public bool InsideConvexHull(Vec3 pos)
        {
            QuadEdge <T> boundEdge = RightMostEdge;

            foreach (QuadEdge <T> hullEdge in boundEdge.RightEdges(CCW:false))
            {
                if (Geometry.RightOf(pos, hullEdge))
                {
                    // Must be outside because hullEdge right face is outside
                    return(false);
                }
            }

            return(true);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Construct triangles based on Delaunay triangulation.
        /// </summary>
        protected override IEnumerable <Vec3> ExportTriangles()
        {
            // FIFO
            var queue = new Queue <QuadEdge <TEdge> >();

            // Start at the far right
            QuadEdge <TEdge> first = _mesh.RightMostEdge;

            queue.Enqueue(first);

            // Visit all edge of the convex hull in CW order and
            // add opposite edges to queue
            foreach (QuadEdge <TEdge> hullEdge in first.RightEdges(CCW:false))
            {
                // Enqueue same edge but with opposite direction
                queue.Enqueue(hullEdge.Sym);
                hullEdge.Tag = !_mesh.VisitedTagState;

                // Because mesh does not have any boundary this is also a triangle
                yield return(hullEdge.Origin);
            }

            // Convex hull now closed. Start triangles construction
            while (queue.Count > 0)
            {
                QuadEdge <TEdge> edge = queue.Dequeue();
                if (edge.Tag == _mesh.VisitedTagState)
                {
                    foreach (QuadEdge <TEdge> current in edge.RightEdges(CCW:false))
                    {
                        if (current.Sym.Tag == _mesh.VisitedTagState)
                        {
                            queue.Enqueue(current.Sym);
                        }
                        current.Tag = !_mesh.VisitedTagState;
                        yield return(current.Origin);
                    }
                }
            }

            // Inverse flag to be able to traverse again at next call
            _mesh.SwitchInternalFlag();
        }