(Version 2) Vector2 Library

Showcase your libraries, tools and other projects that help your fellow love users.
Post Reply
User avatar
XanthicDragon
Prole
Posts: 7
Joined: Fri Feb 13, 2015 7:30 pm

(Version 2) Vector2 Library

Post by XanthicDragon »

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?
  • 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.
Usage notes:

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!)
Here's the code:

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
I hope you enjoy this library! If you find any errors, let me know in the replies below. Thanks.
Last edited by XanthicDragon on Thu May 19, 2016 11:46 am, edited 1 time in total.
"rawr ecksdee" --Xan the Dragon

Baby Inspector is best inspector. No exceptions.
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest