/// <summary> /// Given the polygon perimeters and its drawn chords, construct nodes out of each vertex and lists of each of their /// connected edges into a list of the class ChordSplittingGraphNode which will be used to split the polygon into /// chordless polygons. /// A special case exists where any vertex with four connections needs to be split into two vertices with two /// connections each, because this only happens when a hole shares a vertex with a concave vertex on the outer /// perimeter, and NOT splitting them would cause PolygonSplittingGraph to put them in the same ConnectedNodeGroup /// (thus losing a hole later down the line). /// </summary> /// <param name="allIsoPerims">Array of lists describing the polygon perimeters.</param> /// <param name="bipartiteNodeToChords">Map of all BipartiteNodes to Chords.</param> /// <param name="maxIndependentSet">MIS of BipartiteNodes which contains WHICH chords we should 'draw'.</param> /// <returns>A list of ChordSplittingGraphNodes that describe each vertex of the polygon (with chords included).</returns> private static List <PolygonSplittingGraphNode> _ConstructPolygonSplittingNodes(List <Vector2>[] allIsoPerims, Dictionary <BipartiteGraphNode, Chord> bipartiteNodeToChords, HashSet <BipartiteGraphNode> maxIndependentSet) { var polygonSplittingNodes = new List <PolygonSplittingGraphNode>(); var vertexToID = new Dictionary <Vector2, int>(); int nodeID = 0; foreach (List <Vector2> perim in allIsoPerims) { for (int i = 0; i < perim.Count - 1; i++) { Vector2 vertex = perim[i]; if (vertexToID.ContainsKey(vertex)) { continue; } vertexToID.Add(vertex, nodeID); nodeID++; } } SortedList <int, List <int> > nodeConnectionsByID = _FindVertexConnections(allIsoPerims, bipartiteNodeToChords, maxIndependentSet, vertexToID); foreach (Vector2 vertex in vertexToID.Keys) { int vertexID = vertexToID[vertex]; var chordSplittingNode = new PolygonSplittingGraphNode(vertexID, nodeConnectionsByID[vertexID], vertex.x, vertex.y); polygonSplittingNodes.Add(chordSplittingNode); } return(polygonSplittingNodes); }
/// <summary> /// Creates PolygonSplittingGraphNodes for each vertex using PolyEdges as connections. /// </summary> /// <param name="polyToTileMap">A Dictionary mapping PolyEdges to their respective TileEdges (although in this /// method we just want the PolyEdges).</param> /// <returns>List of PolygonSplittingGraphNodes that represent the vertices/edges formed by the input PolyEdges</returns> private static SortedList <int, PolygonSplittingGraphNode> _CreatePolygonGraphSplittingNodes(Dictionary <PolyEdge, TileEdge> polyToTileMap) { (Dictionary <Vector2, int> vertexToID, Dictionary <int, Vector2> idToVertex) = _InitialiseVertexIDBiDicts(polyToTileMap); var nodeConnections = new Dictionary <int, HashSet <int> >(); foreach (int id in idToVertex.Keys) { nodeConnections[id] = new HashSet <int>(); } foreach (PolyEdge polyEdge in polyToTileMap.Keys) { int aID = vertexToID[polyEdge.a]; int bID = vertexToID[polyEdge.b]; nodeConnections[aID].Add(bID); nodeConnections[bID].Add(aID); } var polygonNodes = new SortedList <int, PolygonSplittingGraphNode>(); foreach (int id in idToVertex.Keys) { var node = new PolygonSplittingGraphNode(id, nodeConnections[id].ToList(), idToVertex[id].x, idToVertex[id].y); polygonNodes.Add(id, node); } return(polygonNodes); }