Vec2 = {} Vec2.__eq = function(a, b) return a.x == b.x and a.y == b.y end Vec2.__index = Vec2 Vec2.__add = function(a, b) return vec2(a.x + b.x, a.y + b.y) end Vec2.__unm = function(a) return vec2(-a.x, -a.y) end Vec2.__sub = function(a, b) return a + (-b) end Vec2.__mul = function(a, b) if (type(b) == "number") then return vec2(a.x * b, a.y * b) end -- scalar mult return vec2(a.x * b.x, a.y * b.y) end Vec2.__div = function(a, b) if (type(b) == "number") then return vec2(a.x / b, a.y / b) end -- scalar mult return vec2(a.x / b.x, a.y / b.y) end Vec2.__tostring = function(a) return "(" .. fmt(a.x) .. "," .. fmt(a.y) .. ")" end function Vec2:magnitude() return sqrt(self.x * self.x + self.y * self.y) end function Vec2:normal() local m = self:magnitude() if m == 0 then return vec2(self.x, self.y) end return self / m end function Vec2:apply(f) return vec2(f(self.x), f(self.y)) end function vec2(x, y) if type(x) == "table" then return vec2(x.x, x.y) end return setmetatable({ x = x, y = y }, Vec2) end function normalize_scalar(x) if x == 0 then return 0 end if x < 0 then return -1 end return 1 end