diff --git a/data/scripts/types/vector2.lua b/data/scripts/types/vector2.lua new file mode 100644 index 0000000..b72e9a0 --- /dev/null +++ b/data/scripts/types/vector2.lua @@ -0,0 +1,167 @@ +local sqrt = math.sqrt +local pow = math.pow + +local function prototype() + return { + x = 0, + y = 0, + + _CLASS_ = "Vector2", + } +end + +local Vector2 = prototype() + +setmetatable(Vector2, Vector2) +Vector2.__index = Vector2 + +local function is_weak_vector2(t) + if type(t) ~= "table" then return false end + + local haskeys = t.x ~= nil and t.y ~= nil + if not haskeys then + return type(t[1]) == "number" and type(t[2]) == "number" + else + return type(t.x) == "number" and type(t.y) == "number" + end +end + +function Vector2:__call(...) + local args = {...} + local nv = prototype() + setmetatable(nv, Vector2) + if type(args[1]) == "number" then + if #args == 1 then + nv.x, nv.y = args[1], args[1] + else + nv.x, nv.y = args[1], args[2] + end + elseif type(args[1]) == "table" then + if args[1].x ~= nil then + nv.x, nv.y = args[1].x, args[1].y + else + nv.x, nv.y = args[1][1], args[1][2] + end + end + return nv +end + +function Vector2:__unm() + return Vector2{ + -self.x, + -self.y, + } +end + +function Vector2:__mul(b) + if type(b) == "number" then + return Vector2{ + self.x * b, + self.y * b, + } + elseif is_weak_vector2(b) then + local other = Vector2(b) + return Vector2{ + self.x * other.x, + self.y * other.y, + } + end + + error("Vector2: other must be either a number or a Vector2-like table.") + return Vector2() +end + +function Vector2:__div(b) + if type(b) == "number" then + return Vector2{ + self.x / b, + self.y / b, + } + elseif is_weak_vector2(b) then + local other = Vector2(b) + return Vector2{ + self.x / other.x, + self.y / other.y, + } + end + + error("Vector2: other must be either a number or a Vector2-like table.") + return Vector2() +end + +function Vector2:__add(b) + if not is_weak_vector2(b) then + error("Vector2: other must be a Vector2-like table.") + return Vector2() + end + local other = Vector2(b) + return Vector2{ + self.x + other.x, + self.y + other.y, + } +end + +function Vector2:__sub(b) + if not is_weak_vector2(b) then + error("Vector2: other must be a Vector2-like table.") + return Vector2() + end + local other = Vector2(b) + return Vector2{ + self.x - other.x, + self.y - other.y, + } +end + +function Vector2:__tostring() + return "Vector2(" .. tostring(self.x) .. ", " .. tostring(self.y) .. ")" +end + +function Vector2:__eq(b) + if not is_weak_vector2(b) then return false end + local other = Vector2(b) + return self.x == other.x and self.y == other.y +end + +--------API-------- +function Vector2:length_squared() + return pow(self.x, 2) + pow(self.y, 2) +end + + +function Vector2:length() + return sqrt(self:length_squared()) +end + +function Vector2:normalized() + local length = self:length() + if length == 0 then + error("Vector2: vector length is zero. Returning Vector2()") + return Vector2() + end + return Vector2{ + self.x / length, + self.y / length, + } +end + +function Vector2:dot(with) + if not is_weak_vector2(with) then + error("Vector2: with must be a Vector2-like table. Returning 0") + return 0 + end + + local v2 = Vector2(with) + return self.x * v2.x + self.y * v2.y +end + +function Vector2:cross(with) + if not is_weak_vector2(with) then + error("Vector2: with must be a Vector2-like table. Returning 0") + return 0 + end + local v2 = Vector2(with) + return self.x * v2.y - self.y * v2.x +end + +return Vector2 \ No newline at end of file