checkpoint before triforce
[anneal.git] / src / edu / berkeley / qfat / geom / RTree.java
index cd1d217..57f20c8 100644 (file)
@@ -4,17 +4,25 @@ import java.util.*;
 import com.infomatiq.jsi.*;
 import com.infomatiq.jsi.rtree.*;
 
+/** wrapper around the <tt>com.infomatiq.jsi.rtree.RTree</tt> class */
 public class RTree<V extends HasBoundingBox> implements Iterable<V> {
 
     private com.infomatiq.jsi.rtree.RTree rtree =
         new com.infomatiq.jsi.rtree.RTree();
 
-    int lowid = 0;
-    HashMap<Integer, V> idToV = new HashMap<Integer, V>();
-    HashMap<V, Integer> vToId = new HashMap<V, Integer>();
+    private int lowid = 0;
+    private HashMap<Integer, V> idToV     = new HashMap<Integer, V>();
+    private HashMap<V, Integer> vToId     = new HashMap<V, Integer>();
+    private HashMap<V, Rectangle> vToRect = new HashMap<V, Rectangle>();
 
     public Iterator<V> iterator() { return vToId.keySet().iterator(); }
 
+    private final MyIntProcedure myIntProcedure    = new MyIntProcedure();
+    private final Rectangle rect = new Rectangle(0,0,0,0,0,0);
+    private final com.infomatiq.jsi.Point point    = new com.infomatiq.jsi.Point(0,0,0);
+    private V          found   = null;
+    private Visitor<V> visitor = null;
+
     private static final Properties props = new Properties();
     static {
         props.put("MinNodeEntries", "1");
@@ -26,6 +34,7 @@ public class RTree<V extends HasBoundingBox> implements Iterable<V> {
     public void clear() {
         idToV.clear();
         vToId.clear();
+        vToRect.clear();
         rtree.init(props);
     }
 
@@ -34,9 +43,9 @@ public class RTree<V extends HasBoundingBox> implements Iterable<V> {
         int id = lowid++;
         idToV.put(id, v);
         vToId.put(v, id);
-        rtree.add(new com.infomatiq.jsi.Rectangle(v.getMinX(), v.getMinY(), v.getMinZ(),
-                                                  v.getMaxX(), v.getMaxY(), v.getMaxZ()),
-                  id);
+        Rectangle rect = new Rectangle(v.getMinX(), v.getMinY(), v.getMinZ(), v.getMaxX(), v.getMaxY(), v.getMaxZ());
+        rtree.add(rect, id);
+        vToRect.put(v, rect);
     }
 
     public void remove(V v) {
@@ -45,41 +54,43 @@ public class RTree<V extends HasBoundingBox> implements Iterable<V> {
         int id = idi;
         idToV.remove(id);
         vToId.remove(v);
-        rtree.delete(new com.infomatiq.jsi.Rectangle(v.getMinX(), v.getMinY(), v.getMinZ(),
-                                                     v.getMaxX(), v.getMaxY(), v.getMaxZ()),
-                     id);
+        rtree.delete(vToRect.get(v), id);
+        vToRect.remove(v);
     }
 
-    // gross...
-    V found = null;
-    private IntProcedure finder = new IntProcedure() {
-            public boolean execute(int id) {
-                found = idToV.get(id);
-                return false;
-            }
-        };
-
-    public V nearest(Point p) {
-        rtree.nearest(new com.infomatiq.jsi.Point(p.x, p.y, p.z), finder, Float.POSITIVE_INFINITY);
+    public V nearest(Point p) { return nearest(p, null); }
+    public V nearest(Point p, Visitor<V> ip) {
+        point.set(p.x, p.y, p.z);
+        this.visitor = ip;
+        rtree.nearest(point, myIntProcedure, Float.POSITIVE_INFINITY);
+        this.visitor = null;
         V ret = found;
         found = null;
         return ret;
     }
 
-    Visitor<V> visitor = null;
-    private IntProcedure searcher = new IntProcedure() {
-            public boolean execute(int id) {
-                V v = idToV.get(id);
-                visitor.visit(v);
-                return true;
-            }
-        };
-    public void range(HasBoundingBox v, Visitor vis) {
+    public void range(HasBoundingBox v, Visitor<V> vis) {
+        visitor = vis;
+        rect.set(v.getMinX(), v.getMinY(), v.getMinZ(), v.getMaxX(), v.getMaxY(), v.getMaxZ());
+        rtree.intersects(rect, myIntProcedure);
+        visitor = null;
+    }
+
+    public void range(Point p1, Point p2, Visitor<V> vis) {
         visitor = vis;
-        rtree.intersects(new com.infomatiq.jsi.Rectangle(v.getMinX(), v.getMinY(), v.getMinZ(),
-                                                         v.getMaxX(), v.getMaxY(), v.getMaxZ()),
-                         searcher);
+        rect.set(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);
+        rtree.intersects(rect, myIntProcedure);
         visitor = null;
     }
 
+    private class MyIntProcedure implements IntProcedure {
+        public boolean execute(int id) {
+            found = idToV.get(id);
+            if (visitor != null) {
+                return visitor.visit(found);
+            } else {
+                return false;
+            }
+        }
+    }
 }