Skip to content

Commit

Permalink
add pretty print function
Browse files Browse the repository at this point in the history
  • Loading branch information
elbywan committed Mar 29, 2017
1 parent dca913a commit d4f9c13
Show file tree
Hide file tree
Showing 5 changed files with 210 additions and 8 deletions.
54 changes: 53 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,63 @@ Visits each node of the quadtree. (meaning subtrees)
```javascript
quadtree.visit(function(){
// This function is called once for each node.
//this -> this is always the current node.
// *this* is a pointer to the current node.
console.log(this.contents)
})
```

### Pretty print

Outputs the tree and its contents in an eye friendly format.

```javascript
var quadtree = new Quadtree({
width: 10,
height: 10,
maxElements: 1
});

var elementArray = [
element0 = {
x: 0,
y: 0,
toString: function() {
return 0;
}
}, element1 = {
x: 3,
y: 3,
toString: function() {
return 1;
}
}
];

quadtree.pushAll(elementArray);

console.log(quadtree.pretty());
```

Console output :

```
| ROOT
| ------------
└──┐
| NW
| ------------
└──┐
| SE
| ------------
| * Leaf content *
| 1
| NW
| ------------
| * Leaf content *
| 0
```


## Further documentation

You can find the annotated source code [here](http://elbywan.github.io/quadtree-lib/).
Expand Down
47 changes: 47 additions & 0 deletions build/js/quadtree.js
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,53 @@ Quadtree = (function() {
return this;
};

Quadtree.prototype.pretty = function() {
var child, fifo, indent, indentation, isParent, str, top;
str = "";
indent = function(level) {
var j, ref, res, times;
res = "";
for (times = j = ref = level; ref <= 0 ? j < 0 : j > 0; times = ref <= 0 ? ++j : --j) {
res += " ";
}
return res;
};
fifo = [
{
label: "ROOT",
tree: this,
level: 0
}
];
while (fifo.length > 0) {
top = fifo.shift();
indentation = indent(top.level);
str += indentation + "| " + top.label + "\n" + indentation + "| ------------\n";
if (top.tree.oversized.length > 0) {
str += indentation + "| * Oversized elements *\n" + indentation + "| " + top.tree.oversized + "\n";
}
if (top.tree.contents.length > 0) {
str += indentation + "| * Leaf content *\n" + indentation + "| " + top.tree.contents + "\n";
}
isParent = false;
for (child in top.tree.children) {
if (!(top.tree.children[child].tree != null)) {
continue;
}
isParent = true;
fifo.unshift({
label: child,
tree: top.tree.children[child].tree,
level: top.level + 1
});
}
if (isParent) {
str += indentation + "└──┐\n";
}
}
return str;
};

return Quadtree;

})();
Expand Down
4 changes: 2 additions & 2 deletions build/js/quadtree.min.js

Large diffs are not rendered by default.

46 changes: 43 additions & 3 deletions src/quadtree.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ class Quadtree
tree = top.tree
elements = top.elements

fifoCandidates = "NW": null, "NE": null, "SW": null, "SE": null
fifoCandidates = { "NW": null, "NE": null, "SW": null, "SE": null }

for element in elements
tree.size++
Expand All @@ -169,12 +169,12 @@ class Quadtree
tree.contents.push element

else
fifoCandidates[direction] ?= tree: relatedChild.get(), elements: []
fifoCandidates[direction] ?= { tree: relatedChild.get(), elements: [] }
fifoCandidates[direction].elements.push(element)

for content in tree.contents
contentDir = calculateDirection content, tree
fifoCandidates[contentDir] ?= tree: tree.children[contentDir].get(), elements: []
fifoCandidates[contentDir] ?= { tree: tree.children[contentDir].get(), elements: [] }
fifoCandidates[contentDir].elements.push(content)

tree.contents = []
Expand Down Expand Up @@ -356,5 +356,45 @@ class Quadtree
fifo.push that.children[child].tree
@

# Pretty printing function.
pretty: () ->
str = ""

indent = (level) ->
res = ""
res += " " for times in [level...0]
res

fifo = [{ label: "ROOT", tree: @, level: 0 }]
while fifo.length > 0
top = fifo.shift()
indentation = indent(top.level)
str += """
#{indentation}| #{top.label}
#{indentation}| ------------\n
"""

if top.tree.oversized.length > 0
str += """
#{indentation}| * Oversized elements *
#{indentation}| #{top.tree.oversized}\n
"""

if top.tree.contents.length > 0
str += """
#{indentation}| * Leaf content *
#{indentation}| #{top.tree.contents}\n
"""

isParent = false
for child of top.tree.children when top.tree.children[child].tree?
isParent = true
fifo.unshift { label: child, tree: top.tree.children[child].tree, level: top.level + 1 }

if isParent then str += "#{indentation}└──┐\n"

str


# Require export.
module?.exports = Quadtree
67 changes: 65 additions & 2 deletions test/test.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ describe 'quadtree', () ->
assert.throws (() -> new Quadtree x:1, y:-1, width:10, height: 10), Error
assert.throws (() -> new Quadtree x:1, y:1, width:0, height: 10), Error
assert.throws (() -> new Quadtree x:1, y:1, width:10, height: -1), Error
assert.throws (() -> new Quadtree x:1, y:1, width:10, height: 10, maxElements: -1), Error

it 'should reject improper elements', () ->
quadtree = new Quadtree width: 100, height: 100
Expand Down Expand Up @@ -45,6 +46,12 @@ describe 'quadtree', () ->
quadtree.remove element
assert.equal quadtree.size, 0

it 'should return false when trying to remove an unknown element', () ->
quadtree = new Quadtree width: 100, height: 100
quadtree.push element = x: 0, y: 0, content: 'element 0'
assert.equal quadtree.remove(x: 10, y: 10), false
assert.equal quadtree.size, 1

it 'should detect colliding elements', () ->
quadtree = new Quadtree width: 100, height: 100
quadtree.pushAll [
Expand All @@ -58,9 +65,9 @@ describe 'quadtree', () ->
element7 = x: 49, y: 50, width: 1, height : 1,
element8 = x: 50, y: 50, width: 1, height : 1,
element9 = x: 99, y: 99,
element10 = x: 99, y: 99]
element10 = x: 99, y: 99 ]

assert.equal quadtree.size,11
assert.equal quadtree.size, 11
assert.equal (quadtree.colliding element0)[0], element1
assert.equal (quadtree.colliding element1)[0], element0
assert.equal (quadtree.colliding element2)[0], element3
Expand Down Expand Up @@ -257,3 +264,59 @@ describe 'quadtree', () ->
assert.equal(whereResult1.length, 0)
assert.equal(whereResult2.length, 2)
assert.equal(whereResult3.length, 1)

it 'should pretty print the quadtree', () ->
quadtree = new Quadtree width: 20, height: 20, maxElements: 2
elementArray = [
element0 = {x: 0, y: 0, toString: () -> 0},
element1 = {x: 2, y: 2, toString: () -> 1},
element2 = {x: 4, y: 4, toString: () -> 2},
element3 = {x: 6, y: 6, toString: () -> 3},
element4 = {x: 8, y: 8, toString: () -> 4},
element5 = {x: 10, y: 8, toString: () -> 5},
element6 = {x: 12, y: 12, toString: () -> 6},
element7 = {x: 8, y: 14, toString: () -> 7},
element8 = {x: 6, y: 16, toString: () -> 8},
element9 = {x: 18, y: 18, toString: () -> 9}
overweight = {x: 10, y: 10, width: 5, height: 5, toString: () -> "overweight"}
]
quadtree.pushAll elementArray

fixedOutput = """
| ROOT
| ------------
└──┐
| SE
| ------------
| * Oversized elements *
| overweight
| * Leaf content *
| 6,9
| SW
| ------------
| * Leaf content *
| 7,8
| NE
| ------------
| * Leaf content *
| 5
| NW
| ------------
└──┐
| SE
| ------------
| * Leaf content *
| 3,4
| NW
| ------------
└──┐
| SE
| ------------
| * Leaf content *
| 1,2
| NW
| ------------
| * Leaf content *
| 0\n
"""
assert.equal(quadtree.pretty(), fixedOutput)

0 comments on commit d4f9c13

Please sign in to comment.