package astar; import java.awt.Graphics; import java.awt.Rectangle; import main.MapObject; public class QuadTree { private QuadTree[] arr; private AStarNode node; private int depth; private int x; private int y; private int width; private int height; public QuadTree(final QuadTree tree1, final QuadTree tree2, final QuadTree tree3, final QuadTree tree4) { (this.arr = new QuadTree[4])[0] = tree1; this.arr[1] = tree2; this.arr[2] = tree3; this.arr[3] = tree4; this.depth = 1; tree1.depth = this.depth + 1; tree2.depth = this.depth + 1; tree3.depth = this.depth + 1; tree4.depth = this.depth + 1; this.node = null; } public QuadTree(final int x, final int y, final int width, final int height) { this.arr = null; this.node = new AStarNode(this); this.x = x; this.y = y; this.width = width; this.height = height; this.depth = 1; } public int getX() { return this.x; } public int getY() { return this.y; } public int getHeight() { return this.height; } public int getWidth() { return this.width; } public int getDepth() { return this.depth; } public boolean isLeaf() { return this.arr == null; } public QuadTree[] getChildren() { return this.arr; } public AStarNode getNode() { return this.node; } public void expandTree(final QuadTree tree1, final QuadTree tree2, final QuadTree tree3, final QuadTree tree4) { if (!this.isLeaf()) { return; } (this.arr = new QuadTree[4])[0] = tree1; this.arr[1] = tree2; this.arr[2] = tree3; this.arr[3] = tree4; tree1.depth = this.depth + 1; tree2.depth = this.depth + 1; tree3.depth = this.depth + 1; tree4.depth = this.depth + 1; this.node = null; } public void addObstacle(final MapObject o) { if (o.getBound() == null) { return; } if (!this.isLeaf()) { this.arr[0].addObstacle(o); this.arr[1].addObstacle(o); this.arr[2].addObstacle(o); this.arr[3].addObstacle(o); return; } final Rectangle square = new Rectangle(this.getX(), this.getY(), this.getWidth(), this.getHeight()); if (!this.getNode().passable || !o.getBound().intersects(square, o)) { return; } if (this.depth == 4 || o.getBound().contains(square, o)) { this.getNode().passable = false; return; } final int newWidth = this.getWidth() / 2; final int newHeight = this.getHeight() / 2; final QuadTree qt1 = new QuadTree(this.getX(), this.getY(), newWidth, newHeight); final QuadTree qt2 = new QuadTree(this.getX() + newWidth, this.getY(), newWidth, newHeight); final QuadTree qt3 = new QuadTree(this.getX(), this.getY() + newHeight, newWidth, newHeight); final QuadTree qt4 = new QuadTree(this.getX() + newWidth, this.getY() + newHeight, newWidth, newHeight); this.expandTree(qt1, qt2, qt3, qt4); this.arr[0].addObstacle(o); this.arr[1].addObstacle(o); this.arr[2].addObstacle(o); this.arr[3].addObstacle(o); } public void coalesce() { if (this.isLeaf()) { return; } this.arr[0].coalesce(); this.arr[1].coalesce(); this.arr[2].coalesce(); this.arr[3].coalesce(); if (!this.arr[0].isLeaf() || this.arr[0].node.passable) { return; } if (!this.arr[1].isLeaf() || this.arr[1].node.passable) { return; } if (!this.arr[2].isLeaf() || this.arr[2].node.passable) { return; } if (!this.arr[3].isLeaf() || this.arr[3].node.passable) { return; } this.x = this.arr[0].x; this.y = this.arr[0].y; this.width = this.arr[0].width * 2; this.height = this.arr[0].height * 2; this.arr = null; this.node = new AStarNode(this); this.node.passable = false; } public void draw(final Graphics g, final int x, final int y, final boolean fill) { if (this.isLeaf()) { if (fill) { g.fillRect(this.getX() + x, this.getY() + y, this.getWidth(), this.getHeight()); } else { g.drawRect(this.getX() + x, this.getY() + y, this.getWidth(), this.getHeight()); } } else { this.arr[0].draw(g, x, y, fill); this.arr[1].draw(g, x, y, fill); this.arr[2].draw(g, x, y, fill); this.arr[3].draw(g, x, y, fill); } } public void drawBlocked(final Graphics g, final int x, final int y) { if (this.isLeaf()) { if (!this.getNode().passable) { g.fillRect(this.getX() + x, this.getY() + y, this.getWidth(), this.getHeight()); } } else { this.arr[0].drawBlocked(g, x, y); this.arr[1].drawBlocked(g, x, y); this.arr[2].drawBlocked(g, x, y); this.arr[3].drawBlocked(g, x, y); } } }