diff --git a/kdtest/Tests.pde b/kdtest/Tests.pde index 71e8df2..18423ec 100644 --- a/kdtest/Tests.pde +++ b/kdtest/Tests.pde @@ -8,3 +8,24 @@ int lineSideTest (float ax0, float ay0, float ax1, float ay1, float px, float py return -1; } } + +boolean contains(BoundingBox a, BoundingBox b) +{//does a contain b? + return b.x1 >= a.x1 && b.x2 <= a.x2 && b.y1 >= a.y1 && b.y2 <= a.y2; +} + +boolean intersects(BoundingBox a, BoundingBox b) +{ + return ((a.x1 <= b.x2 && a.x1 >= b.x1) || (a.x1 <= b.x2 && a.x1 >= b.x1)) &&((a.y1 <= b.y2 && a.y1 >= b.y1) || (a.y1 <= b.y2 && a.y1 >= b.y1)); +} + +boolean inBox(Point p, BoundingBox a) +{ + return p._x >= a.x1 && p._x <= a.x2 && p._y >= a.y1 && p._y <= a.y2; +} +//random helper function I don't know where to put +ArrayList merge(ArrayList a, ArrayList b) { + for(Point p : b) + a.add(p); + return a; +} \ No newline at end of file diff --git a/kdtest/Tree.pde b/kdtest/Tree.pde index 809923b..d07e72e 100644 --- a/kdtest/Tree.pde +++ b/kdtest/Tree.pde @@ -1,11 +1,33 @@ +class BoundingBox { + float x1, x2, y1, y2; + public BoundingBox(float _x1, float _x2, float _y1, float _y2) + { + x1 = _x1; + x2 = _x2; + y1 = _y1; + y2 = _y2; + } + void draw() + { + pushStyle(); + stroke(0); + line(x1, y1, x2, y1); + line(x1, y2, x2, y2); + line(x1, y1, x1, y2); + line(x2, y1, x2, y2); + popStyle(); + } +} + class KdTree { KdTree _left, _right; Point _loc; int _depth; color _c; boolean _dir; // Vertical->True, Horizontal->False - - public KdTree(Point p, boolean vert, int depth) { + BoundingBox _bb; + + public KdTree(Point p, boolean vert, int depth, BoundingBox bb) { _loc = p; _dir = vert; _depth = depth; @@ -13,21 +35,24 @@ class KdTree { _left = null; _right = null; + _bb = bb; } - + + void insert(Point p) { KdTree parent = search(p); + if(parent._dir) { // If parent is vertical if(parent._loc._x > p._x) { - parent._left = new KdTree(p, !parent._dir, parent._depth + 1); + parent._left = new KdTree(p, !parent._dir, parent._depth + 1, new BoundingBox(parent._bb.x1, parent._loc._x, parent._bb.y1, parent._bb.y2)); } else { - parent._right = new KdTree(p, !parent._dir, parent._depth + 1); + parent._right = new KdTree(p, !parent._dir, parent._depth + 1, new BoundingBox(parent._loc._x, parent._bb.x2, parent._bb.y1, parent._bb.y2)); } } else { if(parent._loc._y > p._y) { - parent._left = new KdTree(p, !parent._dir, parent._depth + 1); + parent._left = new KdTree(p, !parent._dir, parent._depth + 1, new BoundingBox(parent._bb.x1, parent._bb.x2, parent._bb.y1, parent._loc._y)); } else { - parent._right = new KdTree(p, !parent._dir, parent._depth + 1); + parent._right = new KdTree(p, !parent._dir, parent._depth + 1, new BoundingBox(parent._bb.x1, parent._bb.x2, parent._loc._y, parent._bb.y2)); } } } @@ -64,7 +89,56 @@ class KdTree { } } + ArrayList report() { + ArrayList rightRes = new ArrayList(); + ArrayList leftRes = new ArrayList(); + + if(isLeaf()) { + leftRes.add(_loc); + return leftRes; + } + if(_left != null) + leftRes = _left.report(); + if(_right != null) + rightRes = _right.report(); + return merge(rightRes, leftRes); + } + + ArrayList query(BoundingBox range) { + ArrayList rightRes = new ArrayList(); + ArrayList leftRes = new ArrayList(); + + if(isLeaf() && inBox(_loc, range)) { + rightRes.add(_loc); + return rightRes; + } + + if(_left != null) { + if(contains(range, _left._bb)) { + leftRes = _left.report(); + } + else if(intersects(_left._bb, range)) { + leftRes = _left.query(range); + } + } + + if(_right != null) { + if(contains(range, _right._bb)) { + rightRes = _right.report(); + } + else if(intersects(_right._bb, range)) { + rightRes = _right.query(range); + } + } + return merge(rightRes, leftRes); + } + + boolean isLeaf() { + return _left==null && _right==null; + } + void draw() { + _bb.draw(); pushStyle(); stroke(_c); if (_left != null) { @@ -82,4 +156,4 @@ class KdTree { float d = depth * 0.2; return color((int)255*cos(d) * cos(d), (int)255*abs(sin(d + PI)), (int)255*abs(sin(d+0.5))); } -} +} \ No newline at end of file diff --git a/kdtest/kdtest.pde b/kdtest/kdtest.pde index 8d01086..3f46b73 100644 --- a/kdtest/kdtest.pde +++ b/kdtest/kdtest.pde @@ -102,6 +102,12 @@ void keyPressed() { case 'E': drawGnoman = !drawGnoman; break; + case '1': + BoundingBox test2 = new BoundingBox(-width/2,width/2,-height/2,height/2); + test2.draw(); + ArrayList pl = tree.query(test2); + println(pl.size()); + break; } } @@ -147,7 +153,7 @@ void mousePressed() { tree.insert(p); } if(tree == null) { - tree = new KdTree (p, true, 0); + tree = new KdTree (p, true, 0, new BoundingBox(-width/2,width/2,-height/2,height/2)); } } cam.mousePressed(); @@ -159,4 +165,4 @@ void mouseDragged() { void mouseReleased() { cam.mouseReleased(); -} +} \ No newline at end of file