private List <Entrance> CreateEntrancesAlongEdge( int startPoint, int endPoint, Cluster precedentCluster, Cluster currentCluster, ref int currentEntranceId, Func <int, Tuple <ConcreteNode, ConcreteNode> > getNodesInEdge, Orientation orientation) { List <Entrance> entrances = new List <Entrance>(); for (var entranceStart = startPoint; entranceStart <= endPoint; entranceStart++) { var size = GetEntranceSize(entranceStart, endPoint, getNodesInEdge); var entranceEnd = entranceStart + size - 1; if (size == 0) { continue; } if (_entranceStyle == EntranceStyle.EndEntrance && size > MAX_ENTRANCE_WIDTH) { var nodes = getNodesInEdge(entranceStart); var srcNode = nodes.Item1; var destNode = nodes.Item2; var entrance1 = new Entrance(Id <Entrance> .From(currentEntranceId), precedentCluster, currentCluster, srcNode, destNode, orientation); currentEntranceId++; nodes = getNodesInEdge(entranceEnd); srcNode = nodes.Item1; destNode = nodes.Item2; var entrance2 = new Entrance(Id <Entrance> .From(currentEntranceId), precedentCluster, currentCluster, srcNode, destNode, orientation); currentEntranceId++; entrances.Add(entrance1); entrances.Add(entrance2); } else { var nodes = getNodesInEdge((entranceEnd + entranceStart) / 2); var srcNode = nodes.Item1; var destNode = nodes.Item2; var entrance = new Entrance(Id <Entrance> .From(currentEntranceId), precedentCluster, currentCluster, srcNode, destNode, orientation); currentEntranceId++; entrances.Add(entrance); } entranceStart = entranceEnd; } return(entrances); }
private void CreateEntranceEdges(Entrance entrance, AbsType type) { var level = entrance.GetEntranceLevel(_clusterSize, _maxLevel); var srcAbstractNodeId = _hierarchicalMap.ConcreteNodeIdToAbstractNodeIdMap[entrance.SrcNode.NodeId]; var destAbstractNodeId = _hierarchicalMap.ConcreteNodeIdToAbstractNodeIdMap[entrance.DestNode.NodeId]; var orientation = entrance.Orientation; int cost = Constants.COST_ONE; switch (type) { case AbsType.ABSTRACT_TILE: case AbsType.ABSTRACT_OCTILE_UNICOST: // Inter-edges: cost 1 cost = Constants.COST_ONE; break; case AbsType.ABSTRACT_OCTILE: { int unitCost; switch (orientation) { case Orientation.Horizontal: case Orientation.Vertical: unitCost = Constants.COST_ONE; break; case Orientation.Hdiag2: case Orientation.Hdiag1: case Orientation.Vdiag1: case Orientation.Vdiag2: unitCost = (Constants.COST_ONE * 34) / 24; break; default: unitCost = -1; break; } cost = unitCost; } break; } _hierarchicalMap.AbstractGraph.AddEdge(srcAbstractNodeId, destAbstractNodeId, new AbstractEdgeInfo(cost, level, true)); _hierarchicalMap.AbstractGraph.AddEdge(destAbstractNodeId, srcAbstractNodeId, new AbstractEdgeInfo(cost, level, true)); }
private List<Entrance> CreateVertEntrances(int y0, int y1, int x, int clusterid1, int clusterid2, int currId, out int lastEntraceId) { var currentIdCounter = currId; var tilingGraph = ConcreteMap.Graph; Func<int, int, Graph<TilingNodeInfo, TilingEdgeInfo>.Node> getNode = (top, left) => tilingGraph.GetNode(ConcreteMap.GetNodeIdFromPos(top, left)); List<Entrance> entrances = new List<Entrance>(); for (var i = y0; i <= y1; i++) { var node1isObstacle = getNode(x, i).Info.IsObstacle; var node2isObstacle = getNode(x + 1, i).Info.IsObstacle; // get the next communication spot if (node1isObstacle || node2isObstacle) continue; // start building the entrance var entranceStart = i; while (true) { i++; if (i >= y1) break; node1isObstacle = getNode(x, i).Info.IsObstacle; node2isObstacle = getNode(x + 1, i).Info.IsObstacle; if (node1isObstacle || node2isObstacle || i >= y1) break; } if (EntranceStyle == EntranceStyle.END_ENTRANCE && (i - entranceStart) > MAX_ENTRANCE_WIDTH) { // create two entrances, one for each end var entrance1 = new Entrance(currentIdCounter++, clusterid1, clusterid2, entranceStart, x, getNode(x, entranceStart).NodeId, getNode(x + 1, entranceStart).NodeId, Orientation.VERTICAL); // BEWARE! We are getting the tileNode for position i - 1. If clustersize was 8 // for example, and end would had finished at 7, you would set the entrance at 6. // This seems to be intended. var entrance2 = new Entrance(currentIdCounter++, clusterid1, clusterid2, (i - 1), x, getNode(x, i - 1).NodeId, getNode(x + 1, i - 1).NodeId, Orientation.VERTICAL); entrances.Add(entrance1); entrances.Add(entrance2); } else { // create one entrance var entrance = new Entrance(currentIdCounter++, clusterid1, clusterid2, ((i - 1) + entranceStart) / 2, x, getNode(x, (i - 1 + entranceStart) / 2).NodeId, getNode(x + 1, (i - 1 + entranceStart) / 2).NodeId, Orientation.VERTICAL); entrances.Add(entrance); } } lastEntraceId = currentIdCounter; return entrances; }
// TODO: Together with Vert Entrances, refactor the code, they are too similar! /// <summary> /// Creates the horizontal entrances between the two clusters, and returns the last entrance id /// </summary> private List<Entrance> CreateHorizEntrances( int x0, int x1, int y, int clusterid1, int clusterid2, int currId, out int nextId) { var currentIdCounter = currId; var orientation = Orientation.HORIZONTAL; var tilingGraph = ConcreteMap.Graph; Func<int, int, Graph<TilingNodeInfo, TilingEdgeInfo>.Node> getNode = (top, left) => tilingGraph.GetNode(ConcreteMap.GetNodeIdFromPos(top, left)); List<Entrance> entrances = new List<Entrance>(); // rolls over the horizontal edge between x0 and x1 in order to find edges between // the top cluster (latitude marks the other cluster entrance line) for (var i = x0; i <= x1; i++) { var node1isObstacle = getNode(i, y).Info.IsObstacle; var node2isObstacle = getNode(i, y + 1).Info.IsObstacle; // get the next communication spot if (node1isObstacle || node2isObstacle) continue; // start building and tracking the entrance var entranceStart = i; while (true) { i++; if (i >= x1) break; node1isObstacle = getNode(i, y).Info.IsObstacle; node2isObstacle = getNode(i, y + 1).Info.IsObstacle; if (node1isObstacle || node2isObstacle || i >= x1) break; } if (EntranceStyle == EntranceStyle.END_ENTRANCE && i - entranceStart > MAX_ENTRANCE_WIDTH) { // If the tracked entrance is big, create 2 entrance points at the edges of the entrance. // create two new entrances, one for each end var entrance1 = new Entrance(currentIdCounter++, clusterid1, clusterid2, y, entranceStart, getNode(entranceStart, y).NodeId, getNode(entranceStart, y + 1).NodeId, orientation); var entrance2 = new Entrance(currentIdCounter++, clusterid1, clusterid2, y, (i - 1), getNode(i - 1, y).NodeId, getNode(i - 1, y + 1).NodeId, orientation); entrances.Add(entrance1); entrances.Add(entrance2); } else { // if it is small, create one entrance in the middle var entrance = new Entrance(currentIdCounter++, clusterid1, clusterid2, y, ((i - 1) + entranceStart) / 2, getNode(((i - 1) + entranceStart) / 2, y).NodeId, getNode(((i - 1) + entranceStart) / 2, y + 1).NodeId, orientation); entrances.Add(entrance); } } nextId = currentIdCounter; return entrances; }
private void CreateEntranceEdges(Entrance entrance, AbsType type, Dictionary<int, AbsTilingNodeInfo> absNodes) { 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; } var abstractNodeId1 = absNodes[entrance.Coord1Id].Id; var abstractNodeId2 = absNodes[entrance.Coord2Id].Id; switch (type) { case AbsType.ABSTRACT_TILE: case AbsType.ABSTRACT_OCTILE_UNICOST: // Inter-edges: cost 1 var absTilingEdgeInfo1 = new AbsTilingEdgeInfo(Constants.COST_ONE, level, true); var absTilingEdgeInfo2 = new AbsTilingEdgeInfo(Constants.COST_ONE, level, true); HierarchicalMap.AbstractGraph.AddEdge(abstractNodeId1, abstractNodeId2, absTilingEdgeInfo1); HierarchicalMap.AbstractGraph.AddEdge(abstractNodeId2, abstractNodeId1, absTilingEdgeInfo2); break; case AbsType.ABSTRACT_OCTILE: { int unitCost; switch (entrance.Orientation) { case Orientation.HORIZONTAL: case Orientation.VERTICAL: unitCost = Constants.COST_ONE; break; case Orientation.HDIAG2: case Orientation.HDIAG1: case Orientation.VDIAG1: case Orientation.VDIAG2: unitCost = (Constants.COST_ONE * 34) / 24; break; default: unitCost = -1; break; } var absTilingEdgeInfo3 = new AbsTilingEdgeInfo(unitCost, level, true); var absTilingEdgeInfo4 = new AbsTilingEdgeInfo(unitCost, level, true); HierarchicalMap.AbstractGraph.AddEdge(abstractNodeId1, abstractNodeId2, absTilingEdgeInfo3); HierarchicalMap.AbstractGraph.AddEdge(abstractNodeId2, abstractNodeId1, absTilingEdgeInfo4); } break; default: break; } }