private Node2d insertNode(
      Node2d node,
      Point2D p,
      int depth,
      double minx,
      double miny,
      double maxx,
      double maxy) { // add the point p to the set (if it is not already in the set)

    if (node == null) {
      node = new Node2d();
      node.rect = new RectHV(minx, miny, maxx, maxy);
      node.depth = depth;
      node.p = p;
      node.left = null;
      node.right = null;
      size++;
    } else {
      if (node.depth % 2 == 0) {
        if (Point2D.X_ORDER.compare(p, node.p) < 0)
          node.left = insertNode(node.left, p, ++depth, minx, miny, node.p.x(), maxy);
        else node.right = insertNode(node.right, p, ++depth, node.p.x(), miny, maxx, maxy);
      } else {
        if (Point2D.Y_ORDER.compare(p, node.p) < 0)
          node.left = insertNode(node.left, p, ++depth, minx, miny, maxx, node.p.y());
        else node.right = insertNode(node.right, p, ++depth, minx, node.p.y(), maxx, maxy);
      }
    }

    return node;
  }
  private boolean containsNode(Node2d node, Point2D p) {
    if (node == null) return false;

    if (node.p.equals(p)) return true;
    else if (node.depth % 2 == 0) {
      if (Point2D.X_ORDER.compare(p, node.p) < 0) return containsNode(node.left, p);
      else return containsNode(node.right, p);
    } else {
      if (Point2D.Y_ORDER.compare(p, node.p) < 0) return containsNode(node.left, p);
      else return containsNode(node.right, p);
    }
  }