// insert a new node, such as start or target, to the abstract graph and // returns the id of the newly created node in the abstract graph // x and y are the positions where I want to put the node private int InsertStal(HierarchicalMap map, int nodeId, Position pos, int start) { // If the node already existed (for instance, it was the an entrance point already // existing in the graph, we need to keep track of the previous status in order // to be able to restore it once we delete this STAL if (map.AbsNodeIds[nodeId] != Constants.NO_NODE) { m_stalLevel[start] = map.AbstractGraph.GetNodeInfo(map.AbsNodeIds[nodeId]).Level; m_stalEdges[start] = map.GetNodeEdges(nodeId); m_stalUsed[start] = true; return map.AbsNodeIds[nodeId]; } m_stalUsed[start] = false; var cluster = map.FindClusterForPosition(pos); // create global entrance var absNodeId = map.NrNodes; var localEntranceIdx = cluster.AddEntrance(absNodeId, new Position(pos.X - cluster.Origin.X, pos.Y - cluster.Origin.Y)); cluster.UpdatePaths(localEntranceIdx); map.AbsNodeIds[nodeId] = absNodeId; var info = new AbsTilingNodeInfo( absNodeId, 1, cluster.Id, pos, nodeId, localEntranceIdx); map.AbstractGraph.AddNode(absNodeId, info); // add new edges to the abstract graph for (var k = 0; k < cluster.GetNrEntrances() - 1; k++) { if (cluster.AreConnected(localEntranceIdx, k)) { map.AddEdge( cluster.GetGlobalAbsNodeId(k), cluster.GetGlobalAbsNodeId(localEntranceIdx), cluster.GetDistance(localEntranceIdx, k)); map.AddEdge( cluster.GetGlobalAbsNodeId(localEntranceIdx), cluster.GetGlobalAbsNodeId(k), cluster.GetDistance(k, localEntranceIdx)); } } return absNodeId; }
/// <summary> /// Create the asbtract nodes of this graph (composed by the centers of /// the entrances between clusters) /// </summary> private Dictionary<int, AbsTilingNodeInfo> GenerateAbstractNodes(List<Entrance> entrances, List<Cluster> clusters) { var abstractNodeId = 0; var absNodes = new Dictionary<int, AbsTilingNodeInfo>(); foreach (var entrance in entrances) { var cluster1 = clusters[entrance.Cluster1Id]; var cluster2 = clusters[entrance.Cluster2Id]; // Determine the level of this entrance. It is given // by its orientation and its coordinates int level; switch (entrance.Orientation) { case Orientation.HORIZONTAL: level = DetermineLevel(entrance.Coord1.Y); break; case Orientation.VERTICAL: level = DetermineLevel(entrance.Coord1.X); break; default: level = -1; break; } // use absNodes as a local var to check quickly if a node with the same centerId // has been created before AbsTilingNodeInfo absNode; if (!absNodes.TryGetValue(entrance.Coord1Id, out absNode)) { var localEntranceIdx = cluster1.AddEntrance( abstractNodeId, new Position(entrance.Coord1.X - cluster1.Origin.X, entrance.Coord1.Y - cluster1.Origin.Y)); var node = new AbsTilingNodeInfo( abstractNodeId, level, entrance.Cluster1Id, new Position(entrance.Coord1.X, entrance.Coord1.Y), entrance.Coord1Id, localEntranceIdx); absNodes[entrance.Coord1Id] = node; abstractNodeId++; } else { if (level > absNode.Level) absNode.Level = level; } if (!absNodes.TryGetValue(entrance.Coord2Id, out absNode)) { var localEntranceIdx = cluster2.AddEntrance( abstractNodeId, new Position(entrance.Coord2.X - cluster2.Origin.X, entrance.Coord2.Y - cluster2.Origin.Y)); var node = new AbsTilingNodeInfo( abstractNodeId, level, entrance.Cluster2Id, new Position(entrance.Coord2.X, entrance.Coord2.Y), entrance.Coord2Id, localEntranceIdx); absNodes[entrance.Coord2Id] = node; abstractNodeId++; } else { if (level > absNode.Level) absNode.Level = level; } } return absNodes; }