]> git.lizzy.rs Git - hydra-dragonfire.git/blobdiff - builtin/vector.lua
Add path finding
[hydra-dragonfire.git] / builtin / vector.lua
index 654a8393f863908ddc5d56a988832ad46b7c10ef..1b3a3e73dd10b856913d4a25c0ff0d058a208ed8 100644 (file)
@@ -11,6 +11,7 @@ local function arith_mt(...)
                __mul = wrap("*", ...),
                __div = wrap("/", ...),
                __mod = wrap("%", ...),
+               __index = {},
        }
 end
 
@@ -31,23 +32,42 @@ function mt_vec2:__neg()
 end
 
 function mt_vec2:__len()
-       return math.sqrt(self.x ^ 2 + self.y ^ 2)
+       return math.sqrt(self:dot(self))
+end
+
+function mt_vec2:__equ(other)
+       return type(other) == "table" and self.x == other.x and self.y == other.y
 end
 
 function mt_vec2:__tostring()
        return "(" .. self.x .. ", " .. self.y .. ")"
 end
 
-mt_vec2.__index = {
-       validate = function(self)
-               assert(type(self.x) == "number")
-               assert(type(self.y) == "number")
-               return self
-       end,
-       round = function(self)
-               return vec2(math.round(self.x), math.round(self.y))
-       end,
-}
+function mt_vec2.__index:validate()
+       assert(type(self.x) == "number")
+       assert(type(self.y) == "number")
+       return self
+end
+
+function mt_vec2.__index:round()
+       return vec2(math.round(self.x), math.round(self.y))
+end
+
+function mt_vec2.__index:manhattan()
+       return math.abs(self.x) + math.abs(self.y)
+end
+
+function mt_vec2.__index:volume()
+       return self.x * self.y
+end
+
+function mt_vec2.__index:dot(other)
+       return self.x * other.x + self.y * other.y
+end
+
+function mt_vec2.__index:norm()
+       return self / #self
+end
 
 function vec2(a, b)
        local o = {}
@@ -81,24 +101,51 @@ function mt_vec3:__neg()
 end
 
 function mt_vec3:__len()
-       return math.sqrt(self.x ^ 2 + self.y ^ 2 + self.z ^ 2)
+       return math.sqrt(self:dot(self))
+end
+
+function mt_vec3:__equ(other)
+       return type(other) == "table" and self.x == other.x and self.y == other.y and self.z == other.z
 end
 
 function mt_vec3:__tostring()
        return "(" .. self.x .. ", " .. self.y .. ", " .. self.z .. ")"
 end
 
-mt_vec3.__index = {
-       validate = function(self)
-               assert(type(self.x) == "number")
-               assert(type(self.y) == "number")
-               assert(type(self.z) == "number")
-               return self
-       end,
-       round = function(self)
-               return vec3(math.floor(self.x), math.floor(self.y), math.floor(self.z))
-       end,
-}
+function mt_vec3.__index:validate()
+       assert(type(self.x) == "number")
+       assert(type(self.y) == "number")
+       assert(type(self.z) == "number")
+       return self
+end
+
+function mt_vec3.__index:round()
+       return vec3(math.floor(self.x), math.floor(self.y), math.floor(self.z))
+end
+
+function mt_vec3.__index:manhattan()
+       return math.abs(self.x) + math.abs(self.y) + math.abs(self.z)
+end
+
+function mt_vec3.__index:volume()
+       return self.x * self.y * self.z
+end
+
+function mt_vec3.__index:dot(other)
+       return self.x * other.x + self.y * other.y + self.z * other.z
+end
+
+function mt_vec3.__index:cross(other)
+       return vec3(
+               self.y * other.z - self.z * other.y,
+               self.z * other.x - self.x * other.z,
+               self.x * other.y - self.y * other.x
+       )
+end
+
+function mt_vec3.__index:norm()
+       return self / #self
+end
 
 function vec3(a, b, c)
        local o = {}
@@ -127,28 +174,40 @@ function mt_box:__neg()
        return box(-self.min, -self.max)
 end
 
+function mt_box:__eq(other)
+       return self.min == other.min and self.max == other.max
+end
+
 function mt_box:__tostring()
        return "[" .. self.min .. "; " .. self.max .. "]"
 end
 
-mt_box.__index = {
-       contains = function(a, b)
-               if type(b) == "number" or b.x then
-                       return a.min <= b and a.max >= b
-               else
-                       return a.min <= b.min and a.max >= b.max
-               end
-       end,
-       validate = function(self)
-               if type(self.min) == "number" then
-                       assert(type(self.max) == "number")
-               else
-                       assert(not self.min.z == not self.max.z)
-                       self.min:validate()
-                       self.max:validate()
-               end
-       end,
-}
+function mt_box.__index:validate()
+       if type(self.min) == "number" then
+               assert(type(self.max) == "number")
+       else
+               assert(not self.min.z == not self.max.z)
+               self.min:validate()
+               self.max:validate()
+       end
+end
+
+function mt_box.__index:volume()
+       local diff = self.max - self.min
+       if type(diff) == "number" then
+               return diff
+       else
+               return diff:volume()
+       end
+end
+
+function mt_box.__index:contains(other)
+       if type(other) == "number" or other.x then
+               return self.min <= other and self.max >= other
+       else
+               return self.min <= other.min and self.max >= other.max
+       end
+end
 
 function box(a, b)
        local o = {}