Created
March 16, 2013 02:44
-
-
Save AmanTifli/5174704 to your computer and use it in GitHub Desktop.
My Quadtree
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Quadtree { | |
//maximum entities in each sector | |
private int MAX_ENT = 10; | |
//maximum number of levels | |
private int MAX_LEVELS = 5; | |
private int level; | |
private Array<Entity> collideEntities; | |
private Rectangle bounds; | |
private Quadtree[] nodes; | |
public Quadtree(int pLevel, Rectangle pBounds) { | |
level = pLevel; | |
collideEntities = new Array<Entity>(); | |
bounds = pBounds; | |
nodes = new Quadtree[4]; | |
} | |
/* | |
* Clears the Quadtree | |
*/ | |
public void clear(){ | |
collideEntities.clear(); | |
for(int i = 0; i < nodes.length;i++){ | |
if(nodes[i] != null){ | |
nodes[i].clear(); | |
nodes[i] = null; | |
} | |
} | |
} | |
/* | |
* Splits the node into 4 sub-nodes | |
*/ | |
private void split(){ | |
int subWidth = (int)(bounds.getWidth() / 2); | |
int subHeight = (int)(bounds.getHeight() / 2); | |
int x = (int)bounds.getX(); | |
int y = (int)bounds.getY(); | |
nodes[0] = new Quadtree(level+1, new Rectangle(x + subWidth, y, subWidth, subHeight)); | |
nodes[1] = new Quadtree(level+1, new Rectangle(x, y, subWidth, subHeight)); | |
nodes[2] = new Quadtree(level+1, new Rectangle(x, y + subHeight, subWidth, subHeight)); | |
nodes[3] = new Quadtree(level+1, new Rectangle(x + subWidth, y + subHeight, subWidth, subHeight)); | |
} | |
/* | |
* Determine which node the object belongs to. -1 means | |
* object cannot completely fit within a child node and is part | |
* of the parent node | |
*/ | |
private int getIndex(Entity e){ | |
int index = -1; | |
double verticalMidpoint = bounds.getX() + (bounds.getWidth() / 2); | |
double horizontalMidpoint = bounds.getY() + (bounds.getHeight() / 2); | |
//takes into account the inverted y of libgdx | |
boolean topQuadrant = (e.hitBox.y > horizontalMidpoint); | |
boolean bottomQuadrant = (e.hitBox.y < horizontalMidpoint && e.hitBox.y + e.hitBox.getHeight() < horizontalMidpoint); | |
//checks if in the right quadrant... | |
if(e.hitBox.x > verticalMidpoint) | |
//places in top right | |
if(topQuadrant){ | |
index = 1; | |
//places in bottom right | |
}else if(bottomQuadrant){ | |
index = 3; | |
} | |
//checks if in the left quadrant... | |
if(e.hitBox.x < verticalMidpoint && e.hitBox.x + e.hitBox.getWidth() < verticalMidpoint ) | |
//places in top left | |
if(topQuadrant){ | |
index = 0; | |
//places in top right | |
}else if(bottomQuadrant){ | |
index = 2; | |
} | |
return index; | |
} | |
/* | |
* Determine which node the object belongs to. -1 means | |
* object cannot completely fit within a child node and is part | |
* of the parent node but this time takes a rectangle as an | |
* argument | |
*/ | |
private int getIndex(Rectangle rect){ | |
int index = -1; | |
double verticalMidpoint = bounds.getX() + (bounds.getWidth() / 2); | |
double horizontalMidpoint = bounds.getY() + (bounds.getHeight() / 2); | |
//takes into account the inverted y of libgdx | |
boolean topQuadrant = (rect.y > horizontalMidpoint); | |
boolean bottomQuadrant = (rect.y < horizontalMidpoint && rect.y + rect.getHeight() < horizontalMidpoint); | |
//checks if in the right quadrant... | |
if(rect.x > verticalMidpoint) | |
//places in top right | |
if(topQuadrant){ | |
index = 1; | |
//places in bottom right | |
}else if(bottomQuadrant){ | |
index = 3; | |
} | |
//checks if in the left quadrant... | |
if(rect.x < verticalMidpoint && rect.x + rect.getWidth() < verticalMidpoint ) | |
//places in top left | |
if(topQuadrant){ | |
index = 0; | |
//places in top right | |
}else if(bottomQuadrant){ | |
index = 2; | |
} | |
return index; | |
} | |
public void insert(Entity e){ | |
if (nodes[0] != null) { | |
int index = getIndex(e); | |
if (index != -1) { | |
nodes[index].insert(e); | |
return; | |
} | |
} | |
collideEntities.add(e); | |
if(collideEntities.size > MAX_ENT && level < MAX_LEVELS){ | |
if (nodes[0] == null) { | |
split(); | |
} | |
int i = 0; | |
while (i < collideEntities.size) { | |
int index = getIndex(collideEntities.get(i)); | |
if (index != -1) { | |
nodes[index].insert(collideEntities.removeIndex(i)); | |
}else{i++;} | |
} | |
} | |
} | |
public Array<Entity> retrieve(Array<Entity> returnEntities, Entity e){ | |
int index = getIndex(e); | |
if (index != -1 && nodes[0] != null) { | |
nodes[index].retrieve(returnEntities, e); | |
} | |
returnEntities.addAll(collideEntities); | |
return returnEntities; | |
} | |
public Array<Entity> retrieve(Array<Entity> returnEntities, Rectangle rect){ | |
int index = getIndex(rect); | |
if (index != -1 && nodes[0] != null) { | |
nodes[index].retrieve(returnEntities, rect); | |
} | |
returnEntities.addAll(collideEntities); | |
return returnEntities; | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment