Advertisement
Guest User

quadtree

a guest
Oct 18th, 2018
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.74 KB | None | 0 0
  1. --[[    class/quadtree.lua - Jericho Quadtree Interface
  2.  
  3. ---     This module contains an implementation for a Quadtree datastructure.
  4. --- This Quadtree is mostly used to support low complexity inventory collision
  5. -- detection.
  6.  
  7. --]]
  8.  
  9. local dirs = enum {
  10.     "northwest";
  11.     "northeast";
  12.     "southwest";
  13.     "southeast";
  14.     "none";
  15. }
  16.  
  17. local node = class.define {
  18.     --- \brief Array of four child nodes.
  19.     children = {};
  20.  
  21.     --- \brief The size and width of this node.
  22.     --- NOTE: This should always x, where x > 0 and f(x) = 2^n
  23.     dimension = 2;
  24.  
  25.     --- \brief The value pointed to at this node.
  26.     value = nil;
  27.  
  28.     --- \brief If this node has been subdivided or not
  29.     split = false;
  30.  
  31.     --- \brief ctor.
  32.     --- \p dim - This node's dimensions.
  33.     --- \p val = The initial value for this node.
  34.     __init = function(self, dim, x, y, val)
  35.         self.dimension  = dim
  36.         self.x          = x
  37.         self.y          = y
  38.         self.value      = val
  39.     end;
  40.  
  41.     direction = function(self, x, y)
  42.         local hs = self.dimension / 2
  43.  
  44.         if x >= self.x and x < self.x + hs then
  45.             if y >= self.y and y < self.y + hs then
  46.                 return dirs.northwest
  47.             elseif y >= self.y + hs and y <= self.y + self.dimension then
  48.                 return dirs.southwest
  49.             end
  50.         elseif x >= self.x + hs and x <= self.x + self.dimension then
  51.             if y >= self.y and y < self.y + hs then
  52.                 return dirs.northeast
  53.             elseif y >= self.y + hs and y <= self.y + self.dimension then
  54.                 return dirs.southeast
  55.             end
  56.         else
  57.             return dirs.none
  58.         end
  59.     end;
  60.  
  61.     --- \brief Subdivides this node
  62.     subdivide = function(self)
  63.         assert(self.dimension ~= 1, "Cannot subdivide 1x1 node.")
  64.  
  65.         local hs = self.dimension / 2
  66.  
  67.         self.children[dirs.northwest] = self.__class(self.dimension / 2, self.x     , self.y)
  68.         self.children[dirs.northeast] = self.__class(self.dimension / 2, self.x + hs, self.y)
  69.         self.children[dirs.southwest] = self.__class(self.dimension / 2, self.x + hs, self.y + hs)
  70.         self.children[dirs.southeast] = self.__class(self.dimension / 2, self.x     , self.y + hs)
  71.  
  72.         self.split = true
  73.     end;
  74.  
  75.     insert = function(self, size, x, y, v)
  76.         if self.dimension ~= size then
  77.             local dir = self:direction(x, y)
  78.  
  79.             if not self.split then
  80.                 self:subdivide()
  81.             end
  82.  
  83.             self.children[self:direction(x, y)]:insert(size, x, y, v)
  84.         else
  85.             self.value = v
  86.         end
  87.     end;
  88.  
  89.     get = function(self, x, y)
  90.         if self.split then
  91.             local dir = self:direction(x, y)
  92.             return self.children[dir]:get(x, y)
  93.         end
  94.  
  95.         return self.value
  96.     end
  97. }
  98.  
  99. local quadtree = class.define {
  100.     __init = function(self, size)
  101.         assert(type(size) == "number", "Expected size to be a number, got '" .. type(size) .. "'.")
  102.  
  103.         self.root = node(size, 0, 0)
  104.     end;
  105.  
  106.     insert = function(self, size, x, y, v)
  107.         assert(type(size) == "number", "Expected size to be a number, got '" .. type(size) .. "'.")
  108.         assert(type(x) == "number", "Expected x to be a number, got '" .. type(x) .. "'.")
  109.         assert(type(y) == "number", "Expected y to be a number, got '" .. type(y) .. "'.")
  110.  
  111.         self.root:insert(size, x, y, v)
  112.     end;
  113.  
  114.     get = function(self, x, y)
  115.         assert(type(x) == "number", "Expected x to be a number, got '" .. type(x) .. "'.")
  116.         assert(type(y) == "number", "Expected y to be a number, got '" .. type(y) .. "'.")
  117.  
  118.         return self.root:get(x, y)
  119.     end
  120. }
  121.  
  122. class.quadtree = quadtree
  123. return quadtree
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement