/// <summary> /// Triangulation algorithm of building segments, based on vertices collection /// </summary> /// <param name="vertices">Collection of all predefined vertices (points)</param> /// <returns>Collection of non-intersecting segments which in total form a set of triangles</returns> /// <remarks><see cref="ITriangulation.Triangulate(VertexCollection)"/> implementation</remarks> public List <Edge> Triangulate(VertexCollection vertices) { Util.Check.NotNull(vertices, "Can't triangulate null collection"); var i = 0u; foreach (var v in vertices) { v.Id = i++; } ; var vvertices = vertices.OrderBy(v => v.X).ThenBy(v => v.Y); Vertices = vvertices.ToVertexCollection(); var result = new List <Edge>(); Debug.WriteLine($"Create Super Triangle:"); var superTriangle = GetSuperTriangle(vertices); Debug.WriteLine($"{superTriangle}"); var triangulation = new HashSet <Triangle> { superTriangle }; foreach (var point in vvertices) { var badTriangles = FindBadTriangles(point, triangulation); var polygon = FindHoleBoundaries(badTriangles); foreach (var triangle in badTriangles) { foreach (var vertex in triangle.Vertices) { vertex.AdjacentTriangles.Remove(triangle); } } triangulation.RemoveWhere(triangle => badTriangles.Contains(triangle)); Debug.WriteLine("Start build new triangles"); Debug.WriteLine($"Current point: {point}"); var posibleEdges = polygon.Where(possibleEdge => possibleEdge.Start != point && possibleEdge.End != point).DistinctEdge().ToList(); foreach (var edge in posibleEdges) { Debug.WriteLine($"Edge for new triangle: {edge}"); if ((point.X == edge.Start.X && point.X == edge.End.X) || (point.Y == edge.Start.Y && point.Y == edge.End.Y)) { Debug.WriteLine(new string('-', 20)); Debug.WriteLine("Something wrong"); continue; } var triangle = new Triangle(point, edge.Start, edge.End); triangulation.Add(triangle); } } triangulation.RemoveWhere(t => t.Vertices.Any(v => superTriangle.Vertices.Contains(v))); Triangles = triangulation.ToList(); foreach (var triangle in triangulation) { triangle.Vertices. ForEach(v => v.AdjacentTriangles.RemoveWhere(t => t.Vertices.Intersect(superTriangle.Vertices).Any())); result.AddRange(triangle.Edges); } return(result.DistinctEdge().ToList()); }