X-Git-Url: http://nitlanguage.org diff --git a/lib/geometry/quadtree.nit b/lib/geometry/quadtree.nit index 97c0783..7c3f2d4 100644 --- a/lib/geometry/quadtree.nit +++ b/lib/geometry/quadtree.nit @@ -29,7 +29,7 @@ import pipeline abstract class QuadTree[E: Boxed[Numeric]] super BoxedCollection[E] - protected var center: nullable Point[Numeric] + protected var center: nullable Point[Numeric] = null var data: Array[E] = new Array[E] # ________________ @@ -39,20 +39,14 @@ abstract class QuadTree[E: Boxed[Numeric]] # | 0 | 3 | # |_______|_______| - protected var child0: nullable QuadTree[E] - protected var child1: nullable QuadTree[E] - protected var child2: nullable QuadTree[E] - protected var child3: nullable QuadTree[E] + protected var child0: nullable QuadTree[E] = null + protected var child1: nullable QuadTree[E] = null + protected var child2: nullable QuadTree[E] = null + protected var child3: nullable QuadTree[E] = null # represent the threshold before subdividing the node - protected var item_limit = 4 - protected var parent_node: nullable QuadTree[E] - - # create the quadtree and set the item limit for each node - init(limit: Int) - do - self.item_limit = limit - end + protected var item_limit: Int + protected var parent_node: nullable QuadTree[E] = null # create a node, giving him self as a parent. Used to create children nodes init with_parent(limit: Int, parent: QuadTree[E]) @@ -61,14 +55,14 @@ abstract class QuadTree[E: Boxed[Numeric]] self.parent_node = parent end - redef fun items_overlapping(region :Boxed[Numeric]): SimpleCollection[E] do - var res = new Array[E] - items_overlapping_in(region,res) - return res - end + redef fun items_overlapping(region): SimpleCollection[E] do + var res = new Array[E] + items_overlapping_in(region,res) + return res + end # add the item to the tree, create children if the limit is reached - redef fun add(item: E) do if self.is_leaf then self.data.add(item) else add_to_children(item) + redef fun add(item) do if self.is_leaf then self.data.add(item) else add_to_children(item) private fun add_to_children(item: Boxed[Numeric]) do @@ -92,14 +86,14 @@ abstract class QuadTree[E: Boxed[Numeric]] else if self.center.y > item.top then self.data.add(item) else if self.center.y < item.bottom then - self.data.add(item) + self.data.add(item) else self.data.add(item) end end end - redef fun is_empty: Bool do return data.is_empty and (self.is_leaf or (child0.is_empty and child1.is_empty and child2.is_empty and child3.is_empty)) + redef fun is_empty do return data.is_empty and (self.is_leaf or (child0.is_empty and child1.is_empty and child2.is_empty and child3.is_empty)) # Return whether or not the Node is a leaf of the tree fun is_leaf: Bool do return child0 == null @@ -215,33 +209,42 @@ end # the center of the parent node class SQuadTree[E: Boxed[Numeric]] super QuadTree[E] - + # the width of the current node of the QuadTree var width: Numeric # the height of the current node of the QuadTree var height: Numeric - init(l: Int, c: Point[Numeric], w: Numeric, h: Numeric) + init do - self.item_limit = l - self.center = c - self.width = w - self.height = h + center = new Point[Numeric](width.div(2), height.div(2)) end init with_parent(l: Int, c: Point[Numeric], w: Numeric, h: Numeric, p: QuadTree[E]) do - init(l, c, w, h) + init(l, w, h) + center = c self.parent_node = p end redef fun subdivide do - var two = self.center.x.value_of(2) - var tree = self.center.x.value_of(3) - child0 = new SQuadTree[E].with_parent(self.item_limit, new Point[Numeric](self.center.x/two, self.center.y/two), self.width/two, self.height/two, self) - child1 = new SQuadTree[E].with_parent(self.item_limit, new Point[Numeric](self.center.x/two, (self.center.y*tree)/two), self.width/two, self.height/two, self) - child2 = new SQuadTree[E].with_parent(self.item_limit, new Point[Numeric]((self.center.x*tree)/two, (self.center.y*tree)/two), self.width/two, self.height/two, self) - child3 = new SQuadTree[E].with_parent(self.item_limit, new Point[Numeric]((self.center.x*tree)/two, self.center.y/two), self.width/two, self.height/two, self) + child0 = new SQuadTree[E].with_parent(self.item_limit, new Point[Numeric](self.center.x.div(2), self.center.y.div(2)), self.width.div(2), self.height.div(2), self) + child1 = new SQuadTree[E].with_parent(self.item_limit, new Point[Numeric](self.center.x.div(2), (self.center.y.mul(3)).div(2)), self.width.div(2), self.height.div(2), self) + child2 = new SQuadTree[E].with_parent(self.item_limit, new Point[Numeric]((self.center.x.mul(3)).div(2), (self.center.y.mul(3)).div(2)), self.width.div(2), self.height.div(2), self) + child3 = new SQuadTree[E].with_parent(self.item_limit, new Point[Numeric]((self.center.x.mul(3)).div(2), self.center.y.div(2)), self.width.div(2), self.height.div(2), self) + end + + redef fun to_s + do + var s = "center : {center.to_s}\n" + for d in data do s += d.to_s + if child0 != null then + s += "\nchild0: {child0.to_s}\n" + s += " child1: {child1.to_s}\n" + s += " child2: {child2.to_s}\n" + s += " child3: {child3.to_s}\n" + end + return s end end