package edu.berkeley.qfat.geom;
import javax.media.opengl.*;
import java.util.*;
import com.infomatiq.jsi.*;
import com.infomatiq.jsi.rtree.*;
/** wrapper around the com.infomatiq.jsi.rtree.RTree class */
public class RTree implements Iterable {
private com.infomatiq.jsi.rtree.RTree rtree =
new com.infomatiq.jsi.rtree.RTree();
private int lowid = 0;
private HashMap idToV = new HashMap();
private HashMap vToId = new HashMap();
private HashMap vToRect = new HashMap();
public Iterator 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 visitor = null;
private static final Properties props = new Properties();
static {
props.put("MinNodeEntries", "1");
props.put("MaxNodeEntries", "5");
}
public RTree() { clear(); }
public void clear() {
idToV.clear();
vToId.clear();
vToRect.clear();
rtree.init(props);
}
public void add(V v) { insert(v); }
public void insert(V v) {
int id = lowid++;
idToV.put(id, v);
vToId.put(v, 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) {
Integer idi = vToId.get(v);
if (idi==null) return;
int id = idi;
idToV.remove(id);
vToId.remove(v);
rtree.delete(vToRect.get(v), id);
vToRect.remove(v);
}
public V nearest(Point p) { return nearest(p, null); }
public V nearest(Point p, Visitor 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;
}
public void range(HasBoundingBox v, Visitor 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 vis) {
visitor = vis;
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;
}
}
}
}