示例#1
0
 public boolean insert(Point2D p) {
   if (p.equals(value)) {
     return false;
   }
   if (onLeft(p)) {
     if (left == null) {
       final TreeNode treeNode = newNode(p, this);
       treeNode.rect =
           even
               ? new RectHV(rect.xmin(), rect.ymin(), value.x(), rect.ymax())
               : new RectHV(rect.xmin(), rect.ymin(), rect.xmax(), value.y());
       left = treeNode;
       return true;
     } else {
       return left.insert(p);
     }
   } else if (onRight(p)) {
     if (right == null) {
       TreeNode treeNode = newNode(p, this);
       treeNode.rect =
           even
               ? new RectHV(rect.xmin(), value.y(), rect.xmax(), rect.ymax())
               : new RectHV(rect.xmin(), value.y(), rect.xmax(), rect.ymax());
       right = treeNode;
       return true;
     } else {
       return right.insert(p);
     }
   }
   return false;
 }
示例#2
0
 private int compare(Point2D p, Point2D q, Orientation orientation) {
   if (orientation == Orientation.LR) {
     return Double.compare(p.x(), q.x());
   } else {
     return Double.compare(p.y(), q.y());
   }
 }
示例#3
0
  private boolean onTheRight(final Point2D point, final Point2D current, final boolean vertical) {

    if (vertical) {
      return point.x() >= current.x();
    } else {
      return point.y() >= current.y();
    }
  }
示例#4
0
  private double distanceToVertical(final Point2D p, final Point2D v, final boolean vertical) {

    if (vertical) {
      return Math.abs(p.x() - v.x());
    } else {
      return Math.abs(p.y() - v.y());
    }
  }
示例#5
0
 private void insert1(Point2D p) {
   if (contains(p)) return;
   boolean newAdded = false;
   if (root == null) {
     initRoot(p);
   } else {
     TreeNode curr = root;
     while (true) {
       if (TreeNode.slightlyEquals(p, curr.value)) {
         return;
       }
       if (curr.even) {
         if (p.x() <= curr.value.x()) {
           if (curr.left == null) {
             TreeNode left = newNode(p, curr);
             left.rect =
                 new RectHV(curr.rect.xmin(), curr.rect.ymin(), curr.value.x(), curr.rect.ymax());
             curr.left = left;
             break;
           } else {
             curr = curr.left;
           }
         } else {
           if (curr.right == null) {
             TreeNode right = newNode(p, curr);
             right.rect =
                 new RectHV(curr.value.x(), curr.rect.ymin(), curr.rect.xmax(), curr.rect.ymax());
             curr.right = right;
             break;
           } else {
             curr = curr.right;
           }
         }
       } else {
         if (p.y() < curr.value.y()) {
           if (curr.left == null) {
             TreeNode left = newNode(p, curr);
             left.rect =
                 new RectHV(curr.rect.xmin(), curr.rect.ymin(), curr.rect.xmax(), curr.value.y());
             curr.left = left;
             break;
           } else {
             curr = curr.left;
           }
         } else {
           if (curr.right == null) {
             TreeNode right = newNode(p, curr);
             right.rect =
                 new RectHV(curr.rect.xmin(), curr.value.y(), curr.rect.xmax(), curr.rect.ymax());
             curr.right = right;
             break;
           } else {
             curr = curr.right;
           }
         }
       }
     }
   }
   size++;
 }
示例#6
0
  private KdNode put(
      KdNode nd, Point2D p, int turn, double xmin, double ymin, double xmax, double ymax) {
    if (nd == null) {
      sz++;
      return new KdNode(p, null, null, new RectHV(xmin, ymin, xmax, ymax));
    }

    // Neglect nodes that collides with one
    // Already in the tree
    double ndx = nd.point.x();
    double ndy = nd.point.y();
    if (nd.point.equals(p)) return nd;
    else if (turn == 0) {
      if (p.x() < ndx) {
        nd.left = put(nd.left, p, 1 - turn, xmin, ymin, Math.min(ndx, xmax), ymax);
      } else {
        nd.right = put(nd.right, p, 1 - turn, Math.max(ndx, xmin), ymin, xmax, ymax);
      }
    } else {
      if (p.y() < ndy) {
        nd.left = put(nd.left, p, 1 - turn, xmin, ymin, xmax, Math.min(ndy, ymax));
      } else {
        nd.right = put(nd.right, p, 1 - turn, xmin, Math.max(ndy, ymin), xmax, ymax);
      }
    }

    return nd;
  }
示例#7
0
  private boolean onTheRight(final Point2D point, final RectHV rect, final boolean vertical) {

    if (vertical) {
      return rect.xmin() > point.x();
    } else {
      return rect.ymin() > point.y();
    }
  }
示例#8
0
  private boolean onTheLeft(final Point2D point, final RectHV rect, final boolean vertical) {

    if (vertical) {
      return rect.xmax() < point.x();
    } else {
      return rect.ymax() < point.y();
    }
  }
示例#9
0
 private boolean search(KdNode nd, Point2D p, int turn) {
   if (nd == null) return false;
   if (nd.point.equals(p)) {
     return true;
   } else if (turn == 0) {
     if (p.x() < nd.point.x()) return search(nd.left, p, 1 - turn);
     else return search(nd.right, p, 1 - turn);
   } else {
     if (p.y() < nd.point.y()) return search(nd.left, p, 1 - turn);
     else return search(nd.right, p, 1 - turn);
   }
 }
示例#10
0
  private Point2D find(KdNode nd, double curDist, Point2D target, int turn) {
    Point2D curClosest = null;

    if (nd == null) return curClosest;

    // Pruning
    if (nd.rect.distanceTo(target) > curDist) {
      return null;
    }

    if (nd.point.distanceTo(target) < curDist) {
      curClosest = nd.point;
      curDist = nd.point.distanceTo(target);
    }

    // Always search the plane that target is on according to
    // current node
    if ((turn == 0 && target.x() < nd.point.x()) || (turn == 1 && target.y() < nd.point.y())) {
      Point2D left = find(nd.left, curDist, target, 1 - turn);
      if (left != null && left.distanceTo(target) < curDist) {
        curClosest = left;
        curDist = left.distanceTo(target);
      }
      Point2D right = find(nd.right, curDist, target, 1 - turn);
      if (right != null && right.distanceTo(target) < curDist) {
        curClosest = right;
        curDist = right.distanceTo(target);
      }
    } else {
      Point2D right = find(nd.right, curDist, target, 1 - turn);
      if (right != null && right.distanceTo(target) < curDist) {
        curClosest = right;
        curDist = right.distanceTo(target);
      }
      Point2D left = find(nd.left, curDist, target, 1 - turn);
      if (left != null && left.distanceTo(target) < curDist) {
        curClosest = left;
        curDist = left.distanceTo(target);
      }
    }
    return curClosest;
  }
示例#11
0
  private Point2D findNearest(
      Node x, Point2D p, Point2D nearest, double minDist, Orientation orientation) {
    if (x == null) {
      return nearest;
    }
    Point2D closest = nearest;
    double closestDistance = minDist;
    double distance = x.p.distanceSquaredTo(p);
    if (distance < minDist) {
      closest = x.p;
      closestDistance = distance;
    }
    Node first, second;
    if (orientation == Orientation.LR) {
      if (p.x() < x.p.x()) {
        first = x.lb;
        second = x.rt;
      } else {
        first = x.rt;
        second = x.lb;
      }
    } else {
      if (p.y() < x.p.y()) {
        first = x.lb;
        second = x.rt;
      } else {
        first = x.rt;
        second = x.lb;
      }
    }
    Orientation nextOrientation = orientation.next();
    if (first != null && first.rect.distanceSquaredTo(p) < closestDistance) {
      closest = findNearest(first, p, closest, closestDistance, nextOrientation);
      closestDistance = closest.distanceSquaredTo(p);
    }
    if (second != null && second.rect.distanceSquaredTo(p) < closestDistance) {
      closest = findNearest(second, p, closest, closestDistance, nextOrientation);
    }

    return closest;
  }
示例#12
0
  private Point2D get(final Node x, final Point2D key, final boolean vertical) {

    if (x == null) {
      return null;
    }

    if (x.key.equals(key)) {
      return x.key;
    }

    double cmp;
    if (vertical) {
      cmp = key.x() - x.key.x();
    } else {
      cmp = key.y() - x.key.y();
    }
    if (cmp <= 0) {
      return get(x.left, key, !vertical);
    } else {
      return get(x.right, key, !vertical);
    }
  }
示例#13
0
  private Node put(final Node x, final Point2D key, final boolean vertical) {

    if (x == null) {
      return new Node(key, 1);
    }
    double cmp;
    if (vertical) {
      cmp = key.x() - x.key.x();
    } else {
      cmp = key.y() - x.key.y();
    }
    if (key.equals(x.key)) {
      // do nothing
    } else if (cmp <= 0) {
      x.left = put(x.left, key, !vertical);
      x.N = 1 + size(x.left) + size(x.right);
    } else if (cmp > 0) {
      x.right = put(x.right, key, !vertical);
      x.N = 1 + size(x.left) + size(x.right);
    }
    return x;
  }
示例#14
0
 // draw all points to standard draw
 public void draw() {
   for (Point2D point2D : root.subSet(LOWER, HIGHER)) {
     StdDraw.point(point2D.x(), point2D.y());
   }
 }
示例#15
0
 private boolean onRight(final Point2D p) {
   return (even && (p.x() > value.x())) || (!even && (p.y() > value.y()));
 }
示例#16
0
 private boolean onLeft(final Point2D p) {
   return (even && (p.x() <= value.x())) || (!even && (p.y() <= value.y()));
 }
示例#17
0
 private static boolean slightlyEquals(Point2D p1, Point2D p2) {
   return Math.abs(p1.x() - p2.x()) < 0.000001 && Math.abs(p1.y() - p2.y()) < 0.000001;
 }