Skip to content

Instantly share code, notes, and snippets.

@mebens
Created June 30, 2011 01:56
Show Gist options
  • Star 29 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save mebens/1055480 to your computer and use it in GitHub Desktop.
Save mebens/1055480 to your computer and use it in GitHub Desktop.
Vector class for my tutorial on Lua metatables.
Vector = {}
Vector.__index = Vector
function Vector.__add(a, b)
if type(a) == "number" then
return Vector.new(b.x + a, b.y + a)
elseif type(b) == "number" then
return Vector.new(a.x + b, a.y + b)
else
return Vector.new(a.x + b.x, a.y + b.y)
end
end
function Vector.__sub(a, b)
if type(a) == "number" then
return Vector.new(b.x - a, b.y - a)
elseif type(b) == "number" then
return Vector.new(a.x - b, a.y - b)
else
return Vector.new(a.x - b.x, a.y - b.y)
end
end
function Vector.__mul(a, b)
if type(a) == "number" then
return Vector.new(b.x * a, b.y * a)
elseif type(b) == "number" then
return Vector.new(a.x * b, a.y * b)
else
return Vector.new(a.x * b.x, a.y * b.y)
end
end
function Vector.__div(a, b)
if type(a) == "number" then
return Vector.new(b.x / a, b.y / a)
elseif type(b) == "number" then
return Vector.new(a.x / b, a.y / b)
else
return Vector.new(a.x / b.x, a.y / b.y)
end
end
function Vector.__eq(a, b)
return a.x == b.x and a.y == b.y
end
function Vector.__lt(a, b)
return a.x < b.x or (a.x == b.x and a.y < b.y)
end
function Vector.__le(a, b)
return a.x <= b.x and a.y <= b.y
end
function Vector.__tostring(a)
return "(" .. a.x .. ", " .. a.y .. ")"
end
function Vector.new(x, y)
return setmetatable({ x = x or 0, y = y or 0 }, Vector)
end
function Vector.distance(a, b)
return (b - a):len()
end
function Vector:clone()
return Vector.new(self.x, self.y)
end
function Vector:unpack()
return self.x, self.y
end
function Vector:len()
return math.sqrt(self.x * self.x + self.y * self.y)
end
function Vector:lenSq()
return self.x * self.x + self.y * self.y
end
function Vector:normalize()
local len = self:len()
self.x = self.x / len
self.y = self.y / len
return self
end
function Vector:normalized()
return self / self:len()
end
function Vector:rotate(phi)
local c = math.cos(phi)
local s = math.sin(phi)
self.x = c * self.x - s * self.y
self.y = s * self.x + c * self.y
return self
end
function Vector:rotated(phi)
return self:clone():rotate(phi)
end
function Vector:perpendicular()
return Vector.new(-self.y, self.x)
end
function Vector:projectOn(other)
return (self * other) * other / other:lenSq()
end
function Vector:cross(other)
return self.x * other.y - self.y * other.x
end
setmetatable(Vector, { __call = function(_, ...) return Vector.new(...) end })
@johannesgijsbers
Copy link

There's an issue with subtraction and division of a vector with a normal number. The order is wrong when the number is first. E.g.: 1 - Vector(0, 0) will result in Vector(-1, -1). I have a fixed version here: https://gist.github.com/johannesgijsbers/880372fc8800e5d5f3e4

@MarkuBu
Copy link

MarkuBu commented Apr 22, 2017

Can you tell me what's the difference between normalize and normalized?

@lexnewgate
Copy link

@MarkuBu normalize change the vector itself while normalized don't.

@MarkuBu
Copy link

MarkuBu commented May 8, 2017

@lexnewgate Thanks

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