public IEnumerable <int> Build(IEnumerable <Vector2> vertices, IReadOnlyCollection <IEnumerable <int> > holeVertices) { var sortedVertices = vertices.Select((v, index) => new SortedVertex(index, v)) .OrderBy(v => v.Vertex.x).ThenBy(v => v.Vertex.y).ToList(); if (sortedVertices.Count < 3) { throw new ArgumentException($"Minimum vertices count for triangulation is 3, but was {sortedVertices.Count}"); } var convexHull = new HullEdgesList(sortedVertices.Count); var graph = new TriangulationGraph(); convexHull.Add(new HullEdge(1, 1)); convexHull.Add(new HullEdge(0, 0)); graph[new Edge(0, 1)].Insert(2); for (var i = 2; i < sortedVertices.Count; i++) { AddVertexToTriangulation(i, sortedVertices, convexHull, graph); } return(DelaunayTriangulationConverter.ConvertToTriangulation(graph, sortedVertices, holeVertices)); }
private static int FixTriangulationIteratively(int vertexId, List <SortedVertex> vertices, HullEdgesList convexHull, HullEdge.IterationDirections direction, Func <Vector2, Vector2, bool> condition, Action <int, int, int> fixTriangulation) { var iterationsCount = 0; const int maxIterationsCount = 100; var hullVertex = vertexId - 1; var lastVector = vertices[hullVertex].Vertex - vertices[vertexId].Vertex; var nextHullVertex = convexHull[hullVertex].Get(direction); var newVector = vertices[nextHullVertex].Vertex - vertices[vertexId].Vertex; while (condition(lastVector, newVector) && iterationsCount < maxIterationsCount) { fixTriangulation(hullVertex, nextHullVertex, vertexId); hullVertex = nextHullVertex; lastVector = newVector; nextHullVertex = convexHull[hullVertex].Get(direction); newVector = vertices[nextHullVertex].Vertex - vertices[vertexId].Vertex; iterationsCount++; } convexHull[vertexId].Set(direction, hullVertex); return(hullVertex); }
private static void AddVertexToTriangulation(int vertexId, List <SortedVertex> vertices, HullEdgesList convexHull, TriangulationGraph graph) { FixTriangulationIteratively(vertexId, vertices, convexHull, HullEdge.IterationDirections.Right, (v1, v2) => TriangulationHelper.CrossProduct(v1, v2) > -DelaunayTriangulationValidator.Eps, (left, right, outer) => FixTriangulation(left, right, outer, vertices, graph)); var hullVertex = FixTriangulationIteratively(vertexId, vertices, convexHull, HullEdge.IterationDirections.Left, (v1, v2) => TriangulationHelper.CrossProduct(v1, v2) < DelaunayTriangulationValidator.Eps, (left, right, outer) => FixTriangulation(right, left, outer, vertices, graph)); convexHull[convexHull[vertexId].Right].Set(HullEdge.IterationDirections.Left, vertexId); convexHull[hullVertex].Set(HullEdge.IterationDirections.Right, vertexId); }