/// <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); }
/// <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(); }