This code is free to use.
package chase.util;
import java.awt.geom.*;
import java.util.*;
public class RangeBucket2D<K extends Point2D> {
List<K> tree[][];
double bucketX;
double bucketY;
Rectangle2D area;
public RangeBucket2D(Rectangle2D range, int xbucket, int ybucket) {
area = (Rectangle2D)range.clone();
bucketX = range.getWidth()/(double)xbucket;
bucketY = range.getHeight()/(double)ybucket;
tree = new List[xbucket][ybucket];
}
private List<K> getNode(K p) {
int x = (int)((p.getX()-area.getMinX())/bucketX);
int y = (int)((p.getY()-area.getMinY())/bucketY);
if(tree[x][y] == null) tree[x][y] = new ArrayList<K>();
//System.out.println("["+x+","+y+"]");
return tree[x][y];
}
public void add(K p) {
if(area.contains(p)) {
//System.out.print("(" + p.getX()+", "+p.getY()+") = ");
getNode(p).add(p);
}
else System.out.println("Out of range");
}
public boolean contains(K p) {
if(area.contains(p))
return getNode(p).contains(p);
return false;
}
public void remove(K p) {
if(area.contains(p))
getNode(p).remove(p);
}
public List<K> range(Rectangle2D range) {
if(!area.contains(range)) return null;
//top left node
int xMin = (int)((range.getMinX()-area.getMinX())/bucketX);
int yMin = (int)((range.getMinY()-area.getMinY())/bucketY);
int xMax = (int)((range.getMaxX()-area.getMinX())/bucketX)+1;
int yMax = (int)((range.getMaxY()-area.getMinY())/bucketY)+1;
List<K> out = new ArrayList<K>();
for(int x = xMin; x < xMax; x++) {
for(int y = yMin; y < yMax; y++) {
List<K> tmp = tree[x][y];
for(int i=0; tmp != null && i < tmp.size(); i++) {
K p = tmp.get(i);
if(range.contains(p)) out.add(p);
}
}
}
return out;
}
}