--- @class Vec3 --- @field x number --- @field y number --- @field z number local __Vec3 = { x = 0, y = 0, z = 0, } local function __tostring(self) return "Vec3{" .. self.x .. ", " .. self.y .. ", " .. self.z .. "}" end --- @param other Vec3 --- @return Vec3 function __Vec3:add(other) return Vec3 { self.x + other.x, self.y + other.y, self.z + other.z } end --- @param factor number function __Vec3:scale(factor) return Vec3 { self.x * factor, self.y * factor, self.z * factor } end function __Vec3:length() return math.sqrt(self.x ^ 2 + self.y ^ 2 + self.z ^ 2) end function __Vec3:normalize() local length = self:length() if length == 0 then return nil end return Vec3 { self.x / length, self.y / length, self.z / length } end function __Vec3:direction() return math.atan2(self.y, self.x) end --- @param other Vec3 function __Vec3:dot(other) return self.x * other.x + self.y * other.y + self.z * other.z end --- @param other Vec3 function __Vec3:angle_to(other) return (other - self):direction() end function __Vec3:floor() return Vec3 { math.floor(self.x), math.floor(self.y), math.floor(self.z) } end function __Vec3:invert() return self:scale(-1) end --- @param other Vec3 function __Vec3:subtract(other) return self:add(other:invert()) end --- @param other Vec3 function __Vec3:equalsTo(other) return self.x == other.x and self.y == other.y and self.z == other.z end ---Vec3 constructor ---@param vec number[] function Vec3(vec) return setmetatable({ x = vec[1] or 0, y = vec[2] or 0, z = vec[3] or 0, }, { __index = __Vec3, __tostring = __tostring, __add = __Vec3.add, __mul = __Vec3.scale, __unm = __Vec3.invert, __sub = __Vec3.subtract, __eq = __Vec3.equalsTo }) end return Vec3