private JPSNode[] getJPSNeighbours(JPSNode current, List<IObstacle> obsList) { double x = current.getX(); double y = current.getY(); LinkedList<JPSNode> nodes = new LinkedList<JPSNode>(); JPSNode parent = current.came_from; if (parent != null) { // determines whether to prune neighbors JPSNode norm = normalizeDirection(x, y, parent.getX(), parent.getY()); double dx = norm.getX() * coordinateScaling; double dy = norm.getY() * coordinateScaling; JPSNode temp = new JPSNode(current); if (((int) dx & (int) dy) != 0) { // diagonal direction // check straight directions in the direction of the diagonal move if (walkable(temp.setPosition(x, y + dy))) nodes.add(new JPSNode(temp)); if (walkable(temp.setPosition(x + dx, y))) nodes.add(new JPSNode(temp)); if (walkable(temp.setPosition(x + dx, y + dy))) nodes.add(new JPSNode(temp)); // forced neighbor checks if (!walkable(temp.setPosition(x - dx, y))) nodes.add(new JPSNode(temp.shift(0, dy))); if (!walkable(temp.setPosition(x, y - dy))) nodes.add(new JPSNode(temp.shift(dx, 0))); } else { // straight direction if (walkable(temp.setPosition(x + dx, y + dy))) { nodes.add(new JPSNode(temp)); // forced neighbor checks if (!walkable(temp.setPosition(x + dy, y + dx))) nodes.add(new JPSNode(temp.shift(dx, dy))); if (!walkable(temp.setPosition(x - dy, y - dx))) nodes.add(new JPSNode(temp.shift(dx, dy))); } } } else { // no parent, return all that aren't blocked JPSNode[] ns = new JPSNode[] { new JPSNode(x, y - coordinateScaling), new JPSNode(x + coordinateScaling, y - coordinateScaling), new JPSNode(x + coordinateScaling, y), new JPSNode(x + coordinateScaling, y + coordinateScaling), new JPSNode(x, y + coordinateScaling), new JPSNode(x - coordinateScaling, y + coordinateScaling), new JPSNode(x - coordinateScaling, y), new JPSNode(x - coordinateScaling, y - coordinateScaling) }; for (int i = 0; i < ns.length; i++) { if (walkable(ns[i])) nodes.add(ns[i]); } } return nodes.toArray(new JPSNode[nodes.size()]); }
private JPSNode jump(JPSNode node, JPSNode parent, JPSNode goal) { double x = node.getX(), y = node.getY(), px = parent.getX(), py = parent.getY(); double dx = (x - px); double dy = (y - py); // Log.e("Coordinatescaling: " + coordinateScaling); // Log.e("dy: " + dy + " dx: " + dx); // Log.e("JUMP! node: " + node.toString() + " parent: " + parent.toString() + " dx: " + dx + " // dy: " + dy); if (!walkable(node)) // check blocked return null; if (node.equals(goal)) // reached goal return new JPSNode(node); // resolve forced neighbors JPSNode temp = new JPSNode(node); if (((int) dx & (int) dy) != 0) { // diagonal if ((walkable(temp.setPosition(x - dx, y + dy)) && !walkable(temp.setPosition(x - dx, y))) || (walkable(temp.setPosition(x + dx, y - dy)) && !walkable(temp.setPosition(x, y - dy)))) { return new JPSNode(node); } // recurse JPSNode h = jump(node.derive(dx, 0), node, goal); if (h != null) return new JPSNode(node); JPSNode v = jump(node.derive(0, dy), node, goal); if (v != null) return new JPSNode(node); } else if (dx == 0) { // vertical, dx = 0, dy = 1 or -1 if ((walkable(temp.setPosition(x + coordinateScaling, y + dy)) && !walkable(temp.setPosition(x + coordinateScaling, y))) || (walkable(temp.setPosition(x - coordinateScaling, y + dy)) && !walkable(temp.setPosition(x - coordinateScaling, y)))) { return new JPSNode(node); } } else { // horizontal, dx = 1 or -1, dy = 0 if ((walkable(temp.setPosition(x + dx, y + coordinateScaling)) && !walkable(temp.setPosition(x, y + coordinateScaling))) || (walkable(temp.setPosition(x + dx, y - coordinateScaling)) && !walkable(temp.setPosition(x, y - coordinateScaling)))) { return new JPSNode(node); } } return jump(node.derive(dx, dy), node, goal); }