松散四叉树

松散四叉树的核心思想
每个子节点的实际大小是标准四叉树的2倍,但逻辑上的划分点不变。

这样,对象即使稍微移动,仍然可能停留在同一个节点中,不需要频繁删除/重新插入。

当查询时,虽然子节点范围更大,但整体查询速度仍然优于普通四叉树。

示意图(普通 vs. 松散四叉树)
普通四叉树:
+----+----+
| 1 | 2 |
+----+----+
| 3 | 4 |
+----+----+
(对象跨越 2,3 节点,需要存储在多个子节点)

松散四叉树(每个子区域放大2倍):
+----+----+
| 1 | 2 |
+----+----+
| 3 | 4 |
+----+----+
(对象跨越区域,但仍然存储在 1 个子节点)

优势
✅ 适合动态对象:

允许对象在一定范围内移动,而无需频繁调整四叉树结构。

比普通四叉树更适合游戏场景(如怪物 AI、子弹碰撞等)。

✅ 查询更高效:

避免对象存储在多个子节点,减少不必要的查询。

✅ 插入/删除性能更好:

由于松散范围,减少了对象需要重新插入的次数。

`
class LooseQuadtree {
class Node {
float x, y, size;
List objects = new ArrayList<>();
Node[] children;

Node(float x, float y, float size) {
this.x = x;
this.y = y;
this.size = size * 2; // 扩大节点范围(松散)
this.children = null;
}

boolean contains(GameObject obj) {
return obj.x >= x - size / 2 && obj.x <= x + size / 2 &&
obj.y >= y - size / 2 && obj.y <= y + size / 2;
}
}

private Node root;

public LooseQuadtree(float x, float y, float size) {
root = new Node(x, y, size);
}

public void insert(GameObject obj) {
insert(root, obj);
}

private void insert(Node node, GameObject obj) {
if (!node.contains(obj)) return; // 物体不在该节点范围内

if (node.children == null) { // 叶子节点
node.objects.add(obj);
return;
}

// 递归插入到子节点
for (Node child : node.children) {
insert(child, obj);
}
}

public List queryRange(float qx, float qy, float qsize) {
return queryRange(root, qx, qy, qsize);
}

private List queryRange(Node node, float qx, float qy, float qsize) {
List results = new ArrayList<>();

if (node == null) return results;
if (!intersects(node, qx, qy, qsize)) return results;

results.addAll(node.objects);

if (node.children != null) {
for (Node child : node.children) {
results.addAll(queryRange(child, qx, qy, qsize));
}
}

return results;
}

private boolean intersects(Node node, float qx, float qy, float qsize) {
return !(node.x - node.size / 2 > qx + qsize / 2 ||
node.x + node.size / 2 < qx - qsize / 2 ||
node.y - node.size / 2 > qy + qsize / 2 ||
node.y + node.size / 2 < qy - qsize / 2);
}
}

class GameObject {
float x, y;
}

`

posted @ 2025-03-26 23:07  ZhangSir游戏老兵  阅读(166)  评论(0)    收藏  举报