local geom = {} local function class(tbl) setmetatable(tbl, tbl) return tbl end -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- -- point -- -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ geom.point = class{ __call = function(this, x, y) local pt = {} pt.x = x pt.y = y setmetatable(pt, {__index=this}) return pt end, distance_to = function(self, pt) local d_x = self.x - pt.x local d_y = self.y - pt.y return math.sqrt(d_x*d_x + d_y*d_y) end, } -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- -- square -- -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ geom.square = class{ __call = function(this, center, span) local square = {} square.center = center square.span = span square.x = this.axis_range(center.x, span/2) square.y = this.axis_range(center.y, span/2) setmetatable(square, {__index=this}) return square end, axis_range = function(c, r) return {min=c-r, max=c+r} end, -- returns true if a point is inside of the square -- and false otherwise -- (x/y mininum exclusive, maximum inclusive) contains = function(self, point) local x_overlap = (point.x > self.x.min) and (point.x <= self.x.max) local y_overlap = (point.y > self.y.min) and (point.y <= self.y.max) if x_overlap and y_overlap then return true end return false end, -- return an array of four squares covering the same -- area as their parent divide = function(self) local this = getmetatable(self).__index local x = self.center.x local y = self.center.y local d = self.span / 4 return { this(geom.point(x-d, y-d), d*2), this(geom.point(x+d, y-d), d*2), this(geom.point(x-d, y+d), d*2), this(geom.point(x+d, y+d), d*2), } end } return geom