-
Notifications
You must be signed in to change notification settings - Fork 1
Vec.lua
Vec.lua is a vector class library for game development. It is designed to be loaded like so:
local Vec = require("Vec")(VECTOR)The function returned by Vec returns a local vector lib object, assigns the vector lib object to any variable arguments, and assigns the vector lib object to global context items to locations defined by any string arguments. This vector lib object can then be used to define new vector objects, like so:
local vec = Vec(0,0)The new vector has an x component of 0 and a y component of 0. The local variable foo becomes the new vector object, and can now be used as such. The vector library currently supports the following operations through metamethods:
- (
+) addition- (
-) subtraction- (
*) multiplication- (
/) division- (
%) modulus- (
^) power (this is done via lua's core ^ operator, which may function differently depending on the implementation)- (
..) dot product- (
==) equality check- (
>/<) greater-than/less-than check- (
>=/<=) greater-than-or-equal-to/less-than-or-equal-to check- (
tostring())tostringfunction usage
All the math operations return a new vector with the result, thus potentially impacting performance. The following functions and properties are also supported:
vec.typereturns "vector" (set)vec.areturns the angle of the vector from the origin (math.atan2(vec.y,vec.x))vec.lreturns the length of the vector (can be slow when used repeatedly due to use ofmath.sqrt())vec.nreturns a unit vector of the same angle (make suse ofvec.l, beware!)vec.maxreturns the largest component of the vector (uses>, so negative numbers are considered smaller)vec.minreturns the smallest component of the vector (uses<, so negative numbers are considered smaller)vec.rreturns a vector with the components reversedvec.absreturns a vector with absolute values of the components
vec:dist(vec2)returns the distance between the vectorsvec:copy(dx,dy)vec:copy(dv)copies vec, adding either the delta x and y or the delta vector.vec:dec(vec2)garbageless shorthand forvec = vec - vec2vec:inc(vec2)garbageless shorthand forvec = vec + vec2vec:mul(vec2)garbageless shorthand forvec = vec * vec2vec:div(vec2)garbageless shorthand forvec = vec / vec2vec:mod(vec2)garbageless shorthand forvec = vec % vec2.vec:set(vec2)copies the values of vec2 into vecvec:unpack()returns the x and y components of the vector
vec:del()garbage recycling for vec; pushes vec onto the reuse stack for future vectors to save RAM. Returns the deleted vector, which is safe to use UNTIL another vector is created.
A relatively recent feature, Volatiles, adds the ability to automatically queue vectors for recycling at a controlled time, thus mitigating the garbage pileup from struct math.
(_VECTOR refers to the library object itself)
_VECTOR.volModeA boolean setting. Default false. If true, all vectors are automatically marked as 'volatile' upon creation._VECTOR.volMathA boolean setting. Default false. If true, all results of vector math are marked as 'volatile' upon creation._VECTOR.crunch()Recycles all volatile vectors into the delqueue._VECTOR.stepCrunch()Slower per item than crunch(), but deletes only one item at a time. Should be safe for coroutines.vec:vol()adds vec to the volatile queue.vec:unVol()Removes vec from volatile queue. Searches from end to beginning, thus making it faster the fewer volatiles are created after vec. Will search entire queue if vec is not volatile, but will not cause any further problems.vec:QUVol()Only use if you're certain no volatile vectors have been created since vec. Will simply pop the most recent item out of volatiles. Will do nothing if top item is not vec. (i.e. if vec is not a volatile, or is not the last volatile created)
An example usage of volatility: (note: for this application, I would normally recommend use of garbageless functions rather than volatility)
local Vec = require("Vec")()
local pos,vel,grav = Vec(0,0),Vec(0,0),Vec(0,9.4)
Vec.volMath = true
local intertime = 0.01
local last
function update(dt)
vel = (vel:del()+grav*dt):QUVol()
pos = (pos:del()+vel*dt):QUVol()
last = os.clock()
while os.clock()-last<intertime do
Vec.stepCrunch()
end
endIn this example, assuming "update" is called every frame with a delta time argument in seconds (as in such platforms as LOVE), the object represented by "pos" would accelerate at 9.4 "meters" per second, updating both velocity and position. The previous versions of these vectors are deleted, and the garbage generated by mathematics is crunched at a comfortable rate in the time between updates - a hundredth of a second, roughly, as defined by "intertime."
Do still note that this particular case could be accomplished via use of garbageless functions with ease, making it far more efficient, but that such optimization is not always feasible or convenient - i.e. in the case of complex or staged math, or when the result is a separate item.