(Version 2) Vector2 Library
Posted: Thu May 19, 2016 1:40 am
Hey all!
I spent the past hour or so writing this up - It's a Vector2 library. Good for doing math in 2D space.
Version 2.1:
+ Added the ability to multiply Vector2s with just a number: Vector2.new(2, 2) * 2
* Fixed a bug with the angle function that caused it to give the wrong value.
---
What does this library feature?
Here's the code:
I hope you enjoy this library! If you find any errors, let me know in the replies below. Thanks.
I spent the past hour or so writing this up - It's a Vector2 library. Good for doing math in 2D space.
Version 2.1:
+ Added the ability to multiply Vector2s with just a number: Vector2.new(2, 2) * 2
* Fixed a bug with the angle function that caused it to give the wrong value.
---
What does this library feature?
- Usage of metatables: It is possible to perform arithmetic on two Vector2s without a method: Vector2.new(1, 1) + Vector2.new(2, 2) is perfectly acceptable. Operations: * + / -
- Helpful methods: Comes with a Lerp function, a Magnitude function, a Unit (Direction/Normal) function, and an Angle function.
Code: Select all
--I can perform operations like so:
local a = Vector2.new(1, 3)
local b = Vector2.new(3, 1)
local n = 3
print(tostring(a*b)) -- Outputs [3, 3]
print(tostring(a*n)) -- (NEW!) We can also multiply a Vector2 by just a number. Outputs [3, 9]
--I can lerp like so:
local a = Vector2.new(0, 0)
local b = Vector2.new(0, 10)
local c = a:lerp(b, 0.5) --This moves a towards b by a factor of 0.5 (50%) - c will be Vector2.new(0, 5)
--I find magnitude, unit, and angle like so:
local a = Vector2.new(0, 0)
local b = Vector2.new(0, 10)
local difference = (b-a) --Note that we do b-a.
local angle = a:toAngle(b) --Should return 0
local distance = difference.Magnitude() --Note the parenthesis. Should return 10
local direction = difference.Unit() --Note the parenthesis. Should return [0, 1] (AS A TABLE! To print a Vector2, we MUST put tostring() around it!)
Code: Select all
local vec2 = {}
function vec2.new(x, y)
local x = x or 0
local y = y or 0
local v = {
[1] = x; --First index x
[2] = y; --Second index y
X = x; --Uppercase X property
Y = y; --Uppercase Y property
x = x; --Lowercase x property
y = y; --Lowercase y property
}
v.mt = {} --Our metatable
setmetatable(v, v.mt)
v.Add = function (a, b)
if getmetatable(a) ~= "Vector2" or getmetatable(b) ~= "Vector2" then
return vec2.new()
end
local x = a.X + b.X
local y = a.Y + b.Y
return vec2.new(x, y)
end
v.Subtract = function (a, b)
if getmetatable(a) ~= "Vector2" or getmetatable(b) ~= "Vector2" then
return vec2.new()
end
local x = a.X - b.X
local y = a.Y - b.Y
return vec2.new(x, y)
end
v.Multiply = function (a, b)
if type(a) == "table" and type(b) == "table" then
if getmetatable(a) ~= "Vector2" or getmetatable(b) ~= "Vector2" then
return vec2.new()
end
local x = a.X * b.X
local y = a.Y * b.Y
return vec2.new(x, y)
elseif (type(a) == "number" or type(b) == "number") and not (type(a) == "number" and type("b") == number) then
--A is a number OR b is a number. Not both.
if type(a) == "number" then
--If a is the number.
return vec2.new(b.X * a, b.Y * a)
elseif type(b) == "number" then
--If b is the number.
return vec2.new(a.X * b, a.Y * b)
end
end
return vec2.new()
end
v.Divide = function (a, b)
if type(a) == "table" and type(b) == "table" then
if getmetatable(a) ~= "Vector2" or getmetatable(b) ~= "Vector2" then
return vec2.new()
end
local x = a.X / b.X
local y = a.Y / b.Y
return vec2.new(x, y)
elseif (type(a) == "number" or type(b) == "number") and not (type(a) == "number" and type("b") == number) then
--A is a number OR b is a number. Not both.
if type(a) == "number" then
--If a is the number.
return vec2.new(b.X / a, b.Y / a)
elseif type(b) == "number" then
--If b is the number.
return vec2.new(a.X / b, a.Y / b)
end
end
return vec2.new()
end
v.Print = function (a)
if getmetatable(a) ~= "Vector2" then
return "[NOT A VECTOR]"
end
return "["..tostring(a.X)..", "..tostring(a.Y).."]"
end
--
v.Magnitude = function ()
local x = v.X
local y = v.Y
return math.sqrt((x^2)+(y^2))
end
v.Unit = function ()
local x = v.X
local y = v.Y
local d = math.sqrt((x^2)+(y^2))
local dir = v / vec2.new(d, d)
return dir
end
function v:lerp(a, frac)
if getmetatable(a) ~= "Vector2" then
return vec2.new()
end
local frac = frac or 0
if frac < 0 then
frac = 0
elseif frac > 1 then
frac = 1
end
local a = (a - v) * vec2.new(frac, frac)
return a + v
end
function v:toAngle(a)
if getmetatable(a) ~= "Vector2" then
return vec2.new()
end
return math.atan2(a[2] - v[2], a[1] - v[1]) - math.pi
end
v.mt.__add = v.Add
v.mt.__sub = v.Subtract
v.mt.__div = v.Divide
v.mt.__mul = v.Multiply
v.mt.__tostring = v.Print
v.mt.__metatable = "Vector2"
return v
end
return vec2