Skip to content

Commit

Permalink
Added sample images and added a working spatialquadtree example
Browse files Browse the repository at this point in the history
  • Loading branch information
Jotschi committed May 8, 2011
1 parent 986bac6 commit 697f9ec
Show file tree
Hide file tree
Showing 31 changed files with 259 additions and 96 deletions.
30 changes: 20 additions & 10 deletions src/main/java/at/jotschi/quadtree/AbstractNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@

import java.awt.Dimension;
import java.awt.Point;
import java.util.Map;

public abstract class AbstractNode {
public abstract class AbstractNode<T> {

/**
* Default value for amount of elements
*/
protected final int MAX_ELEMENTS = 4;
protected final static int MAX_ELEMENTS = 4;

/**
* Default value for max depth
*/
protected final int MAX_DEPTH = 4;
protected final static int MAX_DEPTH = 4;

public static enum Cell {
TOP_LEFT, BOTTOM_RIGHT, BOTTOM_LEFT, TOP_RIGHT
Expand All @@ -26,11 +27,7 @@ public static enum Cell {
protected int depth;

public AbstractNode(Point startCoordinates, Dimension bounds, int depth) {
this.startCoordinates = startCoordinates;
this.bounds = bounds;
this.depth = depth;
this.maxDepth = MAX_DEPTH;
this.maxElements = MAX_ELEMENTS;
this(startCoordinates, bounds, depth, MAX_ELEMENTS, MAX_DEPTH);
}

public AbstractNode(Point startCoordinates, Dimension bounds, int depth,
Expand Down Expand Up @@ -69,6 +66,15 @@ public int getMaxElements() {
return this.maxElements;
}

/**
* Returns the depth of this node
*
* @return
*/
public int getDepth() {
return this.depth;
}

/**
* Returns the max depth
*
Expand All @@ -77,7 +83,11 @@ public int getMaxElements() {
public int getMaxDepth() {
return this.maxDepth;
}

public abstract void subdivide();

public abstract void subdivide();

public abstract void clear();

public abstract Map<Cell, AbstractNode<T>> getSubNodes();

}
11 changes: 4 additions & 7 deletions src/main/java/at/jotschi/quadtree/AbstractQuadTree.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
import java.awt.Dimension;
import java.awt.Point;

import at.jotschi.quadtree.impl.PointNode;

public abstract class AbstractQuadTree<T> {

protected Dimension size;
Expand All @@ -14,7 +12,7 @@ public AbstractQuadTree(Point startCoordinates, Dimension size) {
this.size = size;
this.startCoordinates = startCoordinates;
}

/**
* Returns the size
*
Expand All @@ -32,18 +30,17 @@ public Dimension getSize() {
public Point getStartCoordinates() {
return this.startCoordinates;
}

/**
* Clear the QuadTree
*/
public abstract void clear();


/**
* Return the root node of this quad tree
*
* @return
*/
public abstract PointNode<T> getRootNode();
public abstract AbstractNode<T> getRootNode();


}
6 changes: 2 additions & 4 deletions src/main/java/at/jotschi/quadtree/point/PointNode.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package at.jotschi.quadtree.impl;
package at.jotschi.quadtree.point;

import java.awt.Dimension;
import java.awt.Point;
Expand Down Expand Up @@ -59,7 +59,6 @@ public Map<Cell, PointNode<T>> getSubNodes() {
return this.nodes;
}


/**
* Returns the cell of this element
*
Expand Down Expand Up @@ -112,8 +111,7 @@ public Vector<PointNodeElement<T>> getElements() {
* @param coordinates
* @return
*/
public Vector<PointNodeElement<T>> getElements(
Point coordinates) {
public Vector<PointNodeElement<T>> getElements(Point coordinates) {

// Check if this node has already been subdivided. Therefor this node
// should contain no elements
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package at.jotschi.quadtree.impl;
package at.jotschi.quadtree.point;

import java.awt.Point;

Expand All @@ -9,7 +9,6 @@ public class PointNodeElement<T> extends AbstractNodeElement<T> {

public PointNodeElement(Point coordinates, T element) {
super(coordinates, element);
// TODO Auto-generated constructor stub
}

}
2 changes: 1 addition & 1 deletion src/main/java/at/jotschi/quadtree/point/PointQuadTree.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package at.jotschi.quadtree.impl;
package at.jotschi.quadtree.point;

import java.awt.Dimension;
import java.awt.Point;
Expand Down
132 changes: 112 additions & 20 deletions src/main/java/at/jotschi/quadtree/spacial/SpatialNode.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
package at.jotschi.quadtree.impl;
package at.jotschi.quadtree.spacial;

import java.awt.Dimension;
import java.awt.Point;
import java.util.HashMap;
import java.util.Map;

import at.jotschi.quadtree.AbstractNodeElement;
import org.apache.log4j.Logger;

public class SpacialNode<T> extends PointNode<T> {
import at.jotschi.quadtree.AbstractNode;

protected Map<Cell, SpacialNode<T>> nodes = new HashMap<Cell, SpacialNode<T>>();
public class SpatialNode<T> extends AbstractNode {

protected AbstractNodeElement<T> element;
protected Map<Cell, SpatialNode<T>> nodes = new HashMap<Cell, SpatialNode<T>>();

public SpacialNode(Point startCoordinates, Dimension bounds, int depth) {
protected SpatialNodeElement<T> element;

protected static Logger log = Logger.getLogger(SpatialNode.class);

public SpatialNode(Point startCoordinates, Dimension bounds, int depth) {
super(startCoordinates, bounds, depth);
}

public SpacialNode(Point startCoordinates, Dimension bounds, int depth,
public SpatialNode(Point startCoordinates, Dimension bounds, int depth,
int maxDepth, int maxChildren) {
super(startCoordinates, bounds, depth, maxDepth, maxChildren);

Expand All @@ -29,32 +33,120 @@ public SpacialNode(Point startCoordinates, Dimension bounds, int depth,
*
* @param element
*/
public void insert(SpacialNodeElement<T> element) {
log.debug("Inserting element into Node at depth " + depth);
public boolean insert(SpatialNodeElement<T> element) {

boolean wMatch = element.getWidth() == this.getBounds().width;
boolean hMatch = element.getHeight() == this.getBounds().height;
boolean fits = wMatch && hMatch;

boolean wSmaller = element.getWidth() < this.getBounds().width;
boolean hSmaller = element.getHeight() < this.getBounds().height;
boolean smaller = wSmaller && hSmaller;

log.debug("Inserting element " + element.getHeight() + " - "
+ element.getWidth());

// Check if this node already contains a element
if (this.element != null) {
return false;
}

// Check if the element fits into this node
if (wMatch && hMatch && this.element == null) {
if (fits && this.nodes.size() == 0) {
element.x = this.startCoordinates.x;
element.y = this.startCoordinates.y;
this.element = element;
return;
}

// We need to subdivide the node if the element is smaller than then the
// dimensions of this node.
if (!(this.depth >= MAX_DEPTH)) {
log.debug("Inserting element at coordinates [" + element.x + "-"
+ element.y + "]");
return true;
} else if (!(this.depth >= MAX_DEPTH) && nodes.size() == 0 && smaller) {
// We need to subdivide the node if the element is smaller than then
// the dimensions of this node.
this.subdivide();
// After subdivision we try to insert the element into one of the subnodes
for (SpatialNode<T> current : nodes.values()) {
if (current.insert(element)) {
return true;
}
}

} else {
// Recall insert for the element. This will try to add the element
// into
// one of the subnodes.
for (SpatialNode<T> current : nodes.values()) {
if (current.insert(element)) {
return true;
}
}

}

// Recall insert for the element. This will try to add the element into
// one of the subnodes.
for (SpacialNode<T> current : nodes.values()) {
current.insert(element);
return false;
}

@Override
/**
* Subdivide the current node and add subnodes
*/
public void subdivide() {
log.debug("Subdividing node at depth " + depth);
int depth = this.depth + 1;

int bx = this.startCoordinates.x;
int by = this.startCoordinates.y;

// Create the bounds for the new cell
Dimension newBounds = new Dimension(this.bounds.width / 2,
this.bounds.height / 2);

// Add new bounds to current start coordinates to calculate the new
// start coordinates
int newXStartCoordinate = bx + newBounds.width;
int newYStartCoordinate = by + newBounds.height;

SpatialNode<T> cellNode = null;

// top left
cellNode = new SpatialNode<T>(new Point(bx, by), newBounds, depth);
this.nodes.put(Cell.TOP_LEFT, cellNode);

// top right
cellNode = new SpatialNode<T>(new Point(newXStartCoordinate, by),
newBounds, depth);
this.nodes.put(Cell.TOP_RIGHT, cellNode);

// bottom left
cellNode = new SpatialNode<T>(new Point(bx, newYStartCoordinate),
newBounds, depth);
this.nodes.put(Cell.BOTTOM_LEFT, cellNode);

// bottom right
cellNode = new SpatialNode<T>(new Point(newXStartCoordinate,
newYStartCoordinate), newBounds, depth);
this.nodes.put(Cell.BOTTOM_RIGHT, cellNode);
}

/**
* Clears this node and all subnodes
*/
public void clear() {
for (SpatialNode<T> node : nodes.values()) {
node.clear();
}
}

public SpatialNodeElement<T> getElement() {
return this.element;
}

/**
* Returns the subnodes of this node
*
* @return
*/
public Map<Cell, SpatialNode<T>> getSubNodes() {
return this.nodes;
}

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package at.jotschi.quadtree.impl;
package at.jotschi.quadtree.spacial;

import java.awt.Dimension;
import java.awt.Point;
Expand All @@ -7,16 +7,16 @@


@SuppressWarnings("serial")
public class SpacialNodeElement<T> extends AbstractNodeElement<T> {
public class SpatialNodeElement<T> extends AbstractNodeElement<T> {

protected Dimension elementSize;

public SpacialNodeElement(T element, Dimension elementSize) {
public SpatialNodeElement(T element, Dimension elementSize) {
super(element);
this.elementSize = elementSize;
}

public SpacialNodeElement(Point coordinates, Dimension elementSize, T element) {
public SpatialNodeElement(Point coordinates, Dimension elementSize, T element) {
super(coordinates, element);
this.elementSize = elementSize;
}
Expand Down
Loading

0 comments on commit 697f9ec

Please sign in to comment.