四叉树是一种空间索引结构,它将二维空间划分为四个象限,每个象限可以再继续划分为四个象限,以此类推,直到达到某个终止条件。
在Java中,可以使用以下代码实现四叉树空间索引:
1. 定义QuadTree类
public class QuadTree {
private final int MAX_CAPACITY = 4; // 每个节点最大容量
private final int MAX_LEVEL = 5; // 最大深度
private int level; // 当前深度
private List<Point> points; // 当前节点包含的点
private Rectangle boundary; // 当前节点的边界
private QuadTree[] children; // 子节点
public QuadTree(Rectangle boundary, int level) {
this.boundary = boundary;
this.level = level;
points = new ArrayList<>();
children = null;
}
// 插入点
public boolean insert(Point point) {
if (!boundary.contains(point)) {
return false;
}
if (points.size() < MAX_CAPACITY && children == null) {
points.add(point);
return true;
}
if (children == null) {
split();
}
for (QuadTree child : children) {
if (child.insert(point)) {
return true;
}
}
return false;
}
// 分裂节点
private void split() {
children = new QuadTree[4];
int subWidth = boundary.width / 2;
int subHeight = boundary.height / 2;
int x = boundary.x;
int y = boundary.y;
children[0] = new QuadTree(new Rectangle(x + subWidth, y, subWidth, subHeight), level + 1);
children[1] = new QuadTree(new Rectangle(x, y, subWidth, subHeight), level + 1);
children[2] = new QuadTree(new Rectangle(x, y + subHeight, subWidth, subHeight), level + 1);
children[3] = new QuadTree(new Rectangle(x + subWidth, y + subHeight, subWidth, subHeight), level + 1);
for (Point point : points) {
for (QuadTree child : children) {
if (child.insert(point)) {
break;
}
}
}
points.clear();
}
// 查询某个矩形内的点
public List<Point> query(Rectangle range) {
List<Point> result = new ArrayList<>();
if (!boundary.intersects(range)) {
return result;
}
for (Point point : points) {
if (range.contains(point)) {
result.add(point);
}
}
if (children != null) {
for (QuadTree child : children) {
result.addAll(child.query(range));
}
}
return result;
}
}
2. 定义Point和Rectangle类
public class Point {
public int x;
public int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
public class Rectangle {
public int x;
public int y;
public int width;
public int height;
public Rectangle(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public boolean contains(Point point) {
return point.x >= x && point.x <= x + width && point.y >= y && point.y <= y + height;
}
public boolean intersects(Rectangle range) {
return !(range.x > x + width || range.x + range.width < x || range.y > y + height || range.y + range.height < y);
}
}
3. 使用QuadTree进行空间索引
public class Main {
public static void main(String[] args) {
QuadTree quadTree = new QuadTree(new Rectangle(0, 0, 100, 100), 0);
quadTree.insert(new Point(10, 10));
quadTree.insert(new Point(20, 20));
quadTree.insert(new Point(30, 30));
quadTree.insert(new Point(40, 40));
quadTree.insert(new Point(50, 50));
quadTree.insert(new Point(60, 60));
quadTree.insert(new Point(70, 70));
quadTree.insert(new Point(80, 80));
quadTree.insert(new Point(90, 90));
List<Point> points = quadTree.query(new Rectangle(25, 25, 50, 50));
System.out.println(points);
}
}
输出结果为:[Point{x=30, y=30}, Point{x=40, y=40}, Point{x=50, y=50}, Point{x=60, y=60}, Point{x=70, y=70}],表示查询到了在矩形(25, 25, 50, 50)内的所有点。