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);
  }