Skip to content

Instantly share code, notes, and snippets.

@Rapptz
Created April 25, 2014 22:54
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Rapptz/11305872 to your computer and use it in GitHub Desktop.
Save Rapptz/11305872 to your computer and use it in GitHub Desktop.
local vector = {}
vector.__index = vector
local function is_vector(t)
return getmetatable(t) == vector
end
function vector.new(x, y)
return setmetatable({ x = x or 0, y = y or 0 }, vector)
end
-- operator overloading
function vector.__add(lhs, rhs)
assert(is_vector(lhs) and is_vector(rhs), "Type mismatch: vector expected.")
return vector.new(lhs.x + rhs.x, lhs.x + rhs.x)
end
function vector.__sub(lhs, rhs)
assert(is_vector(lhs) and is_vector(rhs), "Type mismatch: vector expected.")
return vector.new(lhs.x - rhs.x, lhs.x - rhs.x)
end
function vector.__mul(lhs, rhs)
local is_rhs_vector = is_vector(rhs)
local is_lhs_vector = is_vector(lhs)
if type(lhs) == "number" and is_rhs_vector then
return vector.new(rhs.x * lhs, rhs.y * lhs)
elseif type(rhs) == "number" and is_lhs_vector then
return vector.new(lhs.x * rhs, lhs.y * rhs)
elseif is_rhs_vector and is_lhs_vector then
return vector.new(lhs.x * rhs.x, lhs.y * rhs.y)
else
error("Type mismatch: vector and/or number expected", 2)
end
end
function vector.__unm(t)
assert(is_vector(t), "Type mismatch: vector expected.")
return vector.new(-t.x, -t.y)
end
function vector:__tostring()
return "("..self.x..", "..self.y..")"
end
function vector.__eq(lhs, rhs)
return lhs.x == rhs.x and lhs.y == rhs.y
end
function vector.__lt(lhs, rhs)
return lhs.x < rhs.x or (not (rhs.x < lhs.x) and lhs.y < rhs.y)
end
function vector.__le(lhs, rhs)
return lhs.x <= rhs.x or lhs.y <= rhs.y
end
-- actual functions
function vector:clone()
return vector.new(self.x, self.y)
end
function vector:length()
return math.sqrt(self.x * self.x + self.y * self.y)
end
function vector:length_squared()
return self.x * self.x + self.y * self.y
end
function vector:is_unit()
return self:length_squared() == 1
end
function vector:unpack()
return self.x, self.y
end
function vector:normalize()
local len = self:length()
if len ~= 0 and len ~= 1 then
self.x = self.x / len
self.y = self.y / len
end
end
function vector:normalized()
return self:clone():normalize()
end
function vector.dot(lhs, rhs)
assert(is_vector(lhs) and is_vector(rhs), "Type mismatch: vector expected")
return lhs.x * rhs.x + lhs.y * rhs.y
end
function vector.distance(lhs, rhs)
assert(is_vector(lhs) and is_vector(rhs), "Type mismatch: vector expected")
local dx, dy = lhs.x - rhs.x, lhs.y - rhs.y
return math.sqrt(dx * dx + dy * dy)
end
function vector.distance_squared(lhs, rhs)
assert(is_vector(lhs) and is_vector(rhs), "Type mismatch: vector expected")
local dx, dy = lhs.x - rhs.x, lhs.y - rhs.y
return dx * dx + dy * dy
end
function vector.max(lhs, rhs)
assert(is_vector(lhs) and is_vector(rhs), "Type mismatch: vector expected")
local x = math.max(lhs.x, rhs.x)
local y = math.max(lhs.y, rhs.y)
return vector.new(x, y)
end
function vector.min(lhs, rhs)
assert(is_vector(lhs) and is_vector(rhs), "Type mismatch: vector expected")
local x = math.min(lhs.x, rhs.x)
local y = math.min(lhs.y, rhs.y)
return vector.new(x, y)
end
function vector.angle(from, to)
assert(is_vector(from) and is_vector(to), "Type mismatch: vector expected")
return math.acos(vector.dot(from, to) / (from:length() * to:length()))
end
function vector.direction(from, to)
assert(is_vector(from) and is_vector(to), "Type mismatch: vector expected")
return math.atan2(to.y - from.y, to.x - from.y)
end
function vector.lerp(from, to, t)
assert(is_vector(from) and is_vector(to), "Type mismatch: vector expected")
assert(type(t) == "number", "Type mismatch: number expected for t")
return from * t + (to * (1 - t))
end
return vector
@CapsAdmin
Copy link

CapsAdmin commented Dec 12, 2020

in __add and __sub you are making a new vector with the x component only

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment