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(); } }
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(); } }
// all points that are inside the rectangle public Iterable<Point2D> range(RectHV rect) { if (root == null) { return new ArrayList<>(); } requireNonNull(rect); final Point2D lower = new Point2D(rect.xmin(), rect.ymin()); final Point2D higher = new Point2D(rect.xmax(), rect.ymax()); return root.subSet(lower, higher); }
// all points that are inside the rectangle public Iterable<Point2D> range(RectHV rect) { if (rect == null) throw new NullPointerException("rect"); ArrayList<Point2D> rectPoints = new ArrayList<Point2D>(); for (Point2D point : points) { if (rect.contains(point)) rectPoints.add(point); } return rectPoints; }
private void findPoints(ArrayList<Point2D> r, RectHV rect, Node x) { if (!rect.intersects(x.rect)) { return; } if (rect.contains(x.p)) { r.add(x.p); } if (x.lb != null) { findPoints(r, rect, x.lb); } if (x.rt != null) { findPoints(r, rect, x.rt); } }
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; }
// all points that are inside the rectangle public Iterable<Point2D> range(RectHV rect) { if (rect == null) throw new NullPointerException("RectHV cannot be null!"); // Create a queue and fill it with points that are inside rect LinkedQueue<Point2D> q = new LinkedQueue<Point2D>(); for (Point2D point : set) { if (rect.contains(point)) q.enqueue(point); } return q; }
public void range(RectHV rect, List<Point2D> list) { if (left != null && left.rect.intersects(rect)) { left.range(rect, list); } if (rect.contains(value)) { list.add(value); } if (right != null && right.rect.intersects(rect)) { right.range(rect, list); } }
private void collect(TreeSet<Point2D> points, KdNode nd, RectHV rect) { if (nd == null) return; // Pruning, return if the box not intersect with that of the node if (!nd.rect.intersects(rect)) return; if (rect.contains(nd.point)) { points.add(nd.point); } collect(points, nd.left, rect); collect(points, nd.right, rect); }
private void range( final Node node, final RectHV rect, final Queue<Point2D> ranged, final boolean vertical) { if (node == null) { return; } if (rect.contains(node.key)) { ranged.enqueue(node.key); range(node.left, rect, ranged, !vertical); range(node.right, rect, ranged, !vertical); } else { if (onTheLeft(node.key, rect, vertical)) { range(node.left, rect, ranged, !vertical); } else if (onTheRight(node.key, rect, vertical)) { range(node.right, rect, ranged, !vertical); } else { range(node.left, rect, ranged, !vertical); range(node.right, rect, ranged, !vertical); } } }
public static void main(String[] args) { In in = new In("/Users/eugene/Downloads/kdtree/horizontal8.txt"); StdDraw.show(0); // initialize the data structures with N points from standard input // eugeneto.princeton.algorithm.exercises.week5.PointSET brute = new // eugeneto.princeton.algorithm.exercises.week5.PointSET(); KdTree kdtree = new KdTree(); while (!in.isEmpty()) { double x = in.readDouble(); double y = in.readDouble(); Point2D p = new Point2D(x, y); kdtree.insert(p); // brute.insert(p); } double x0 = 0.0, y0 = 0.0; // initial endpoint of rectangle double x1 = 0.0, y1 = 0.0; // current location of mouse boolean isDragging = false; // is the user dragging a rectangle // draw the points StdDraw.clear(); StdDraw.setPenColor(StdDraw.BLACK); StdDraw.setPenRadius(.01); kdtree.draw(); while (true) { StdDraw.show(40); // user starts to drag a rectangle if (StdDraw.mousePressed() && !isDragging) { x0 = StdDraw.mouseX(); y0 = StdDraw.mouseY(); isDragging = true; continue; } // user is dragging a rectangle else if (StdDraw.mousePressed() && isDragging) { x1 = StdDraw.mouseX(); y1 = StdDraw.mouseY(); continue; } // mouse no longer pressed else if (!StdDraw.mousePressed() && isDragging) { isDragging = false; } RectHV rect = new RectHV(Math.min(x0, x1), Math.min(y0, y1), Math.max(x0, x1), Math.max(y0, y1)); // draw the points StdDraw.clear(); StdDraw.setPenColor(StdDraw.BLACK); StdDraw.setPenRadius(.01); kdtree.draw(); // draw the rectangle StdDraw.setPenColor(StdDraw.BLACK); StdDraw.setPenRadius(); rect.draw(); // draw the range search results for brute-force data structure in red StdDraw.setPenRadius(.03); StdDraw.setPenColor(StdDraw.RED); for (Point2D p : kdtree.range(rect)) p.draw(); // draw the range search results for kd-tree in blue StdDraw.setPenRadius(.02); StdDraw.setPenColor(StdDraw.BLUE); for (Point2D p : kdtree.range(rect)) p.draw(); StdDraw.show(40); } }