/** Returns a (random) coordinate that is between two adjacent MapNodes */ @Override public Coord getInitialLocation(boolean translate) { List<MapNode> nodes = map.getNodes(); MapNode n, n2; Coord n2Location, nLocation, placement; double dx, dy; double rnd = rng.nextDouble(); // choose a random node (from OK types if such are defined) do { n = nodes.get(rng.nextInt(nodes.size())); } while (okMapNodeTypes != null && !n.isType(okMapNodeTypes)); // choose a random neighbor of the selected node n2 = n.getNeighbors().get(rng.nextInt(n.getNeighbors().size())); nLocation = n.getLocation(); n2Location = n2.getLocation(); placement = n.getLocation().clone(); dx = rnd * (n2Location.getX() - nLocation.getX()); dy = rnd * (n2Location.getY() - nLocation.getY()); if (translate == false) { dx = 0; dy = 0; } placement.translate(dx, dy); // move coord from n towards n2 this.lastMapNode = n; return placement; }
/** * Checks that all map nodes can be reached from all other map nodes * * @param nodes The list of nodes to check * @throws SettingsError if all map nodes are not connected */ private void checkMapConnectedness(List<MapNode> nodes) { Set<MapNode> visited = new HashSet<MapNode>(); Queue<MapNode> unvisited = new LinkedList<MapNode>(); MapNode firstNode; MapNode next = null; if (nodes.size() == 0) { throw new SimError("No map nodes in the given map"); } firstNode = nodes.get(0); visited.add(firstNode); unvisited.addAll(firstNode.getNeighbors()); while ((next = unvisited.poll()) != null) { visited.add(next); for (MapNode n : next.getNeighbors()) { if (!visited.contains(n) && !unvisited.contains(n)) { unvisited.add(n); } } } if (visited.size() != nodes.size()) { // some node couldn't be reached MapNode disconnected = null; for (MapNode n : nodes) { // find an example node if (!visited.contains(n)) { disconnected = n; break; } } throw new SettingsError( "SimMap is not fully connected. Only " + visited.size() + " out of " + nodes.size() + " map nodes " + "can be reached from " + firstNode + ". E.g. " + disconnected + " can't be reached"); } }
@Override public Path getPath() { Path p = new Path(generateSpeed()); MapNode curNode = lastMapNode; MapNode prevNode = lastMapNode; MapNode nextNode = null; List<MapNode> neighbors; Coord nextCoord; assert lastMapNode != null : "Tried to get a path before placement"; // start paths from current node p.addWaypoint(curNode.getLocation()); int pathLength = rng.nextInt(maxPathLength - minPathLength) + minPathLength; for (int i = 0; i < pathLength; i++) { neighbors = curNode.getNeighbors(); Vector<MapNode> n2 = new Vector<MapNode>(neighbors); if (!this.backAllowed) { n2.remove(prevNode); // to prevent going back } if (okMapNodeTypes != null) { // remove neighbor nodes that aren't ok for (int j = 0; j < n2.size(); ) { if (!n2.get(j).isType(okMapNodeTypes)) { n2.remove(j); } else { j++; } } } if (n2.size() == 0) { // only option is to go back nextNode = prevNode; } else { // choose a random node from remaining neighbors nextNode = n2.get(rng.nextInt(n2.size())); } prevNode = curNode; nextCoord = nextNode.getLocation(); curNode = nextNode; p.addWaypoint(nextCoord); } lastMapNode = curNode; return p; }