hump.vector =========== :: vector = require "hump.vector" A handy 2D vector class providing most of the things you do with vectors. You can access the individual coordinates by ``vec.x`` and ``vec.y``. .. note:: The vectors are stored as tables. Most operations create new vectors and thus new tables, which *may* put **Example**:: function player:update(dt) local delta = vector(0,0) if love.keyboard.isDown('left') then delta.x = -1 elseif love.keyboard.isDown('right') then delta.x = 1 end if love.keyboard.isDown('up') then delta.y = -1 elseif love.keyboard.isDown('down') then delta.y = 1 end delta:normalize_inplace() player.velocity = player.velocity + delta * player.acceleration * dt if player.velocity:len() > player.max_velocity then player.velocity = player.velocity:normalized() * player.max_velocity end player.position = player.position + player.velocity * dt end Vector arithmetic ----------------- **hump** provides vector arithmetic by implement the corresponding metamethods (``__add``, ``__mul``, etc.). Here are the semantics: ``vector + vector = vector`` Component wise sum: \((a,b) + (x,y) = (a+x, b+y)\) ``vector - vector = vector`` Component wise difference: \((a,b) - (x,y) = (a-x, b-y)\) ``vector * vector = number`` Dot product: \((a,b) * (x,y) = a*x + b*y\) ``number * vector = vector`` Scalar multiplication/scaling: \((a,b) * s = (s*a, s*b)\) ``vector * number = vector`` Scalar multiplication/scaling: \(s * (x,y) = (s*x, s*y)\) ``vector / number = vector`` Scalar multiplication/scaling: \((a,b) / s = (a/s, b/s)\). Common relations are also defined: ``a == b`` Same as ``a.x == b.x and a.y == b.y``. ``a <= b`` Same as ``a.x <= b.x and a.y <= b.y``. ``a < b`` Lexicographical order: ``a.x < b.x or (a.x == b.x and a.y < b.y)``. **Example**:: -- acceleration, player.velocity and player.position are vectors acceleration = vector(0,-9) player.velocity = player.velocity + acceleration * dt player.position = player.position + player.velocity * dt Function Reference ------------------ .. function:: vector.new(x,y) :param numbers x,y: Coordinates. :returns: The vector. Create a new vector. **Examples**:: a = vector.new(10,10) :: -- as a shortcut, you can call the module like a function: vector = require "hump.vector" a = vector(10,10) .. function:: vector.isvector(v) :param mixed v: The variable to test. :returns: ``true`` if ``v`` is a vector, ``false`` otherwise. Test whether a variable is a vector. **Example**:: if not vector.isvector(v) then v = vector(v,0) end .. function:: vector.vector:clone() :returns: Copy of the vector. Copy a vector. Assigning a vector to a variable will create a *reference*, so when modifying the vector referenced by the new variable would also change the old one:: a = vector(1,1) -- create vector b = a -- b references a c = a:clone() -- c is a copy of a b.x = 0 -- changes a,b and c print(a,b,c) -- prints '(1,0), (1,0), (1,1)' **Example**:: copy = original:clone() .. function:: vector.vector:unpack() :returns: The coordinates ``x,y``. Extract coordinates. **Examples**:: x,y = pos:unpack() :: love.graphics.draw(self.image, self.pos:unpack()) .. function:: vector.vector:permul(other) :param vector other: The second source vector. :returns: Vector whose components are products of the source vectors. Multiplies vectors coordinate wise, i.e. ``result = vector(a.x * b.x, a.y * b.y)``. This does not change either argument vectors, but creates a new one. **Example**:: -- scale with different magnitudes scaled = original:permul(vector(1,1.5)) .. function:: vector.vector:len() :returns: ``number`` Length of the vector. Get length of a vector, i.e. ``math.sqrt(vec.x * vec.x + vec.y * vec.y)``. **Example**:: distance = (a - b):len() .. function:: vector.vector:len2() :returns: ``number`` Squared length of the vector. Get squared length of a vector, i.e. ``vec.x * vec.x + vec.y * vec.y``. **Example**:: -- get closest vertex to a given vector closest, dsq = vertices[1], (pos - vertices[1]):len2() for i = 2,#vertices do local temp = (pos - vertices[i]):len2() if temp < dsq then closest, dsq = vertices[i], temp end end .. function:: vector.vector:dist(other) :param vector other: Other vector to measure the distance to. :returns: ``number`` The distance of the vectors. Get distance of two vectors. The same as ``(a - b):len()``. **Example**:: -- get closest vertex to a given vector -- slightly slower than the example using len2() closest, dist = vertices[1], pos:dist(vertices[1]) for i = 2,#vertices do local temp = pos:dist(vertices[i]) if temp < dist then closest, dist = vertices[i], temp end end .. function:: vector.vector:dist2(other) :param vector other: Other vector to measure the distance to. :returns: ``number`` The squared distance of the vectors. Get squared distance of two vectors. The same as ``(a - b):len2()``. **Example**:: -- get closest vertex to a given vector -- slightly faster than the example using len2() closest, dsq = vertices[1], pos:dist2(vertices[1]) for i = 2,#vertices do local temp = pos:dist2(vertices[i]) if temp < dsq then closest, dsq = vertices[i], temp end end .. function:: vector.vector:normalized() :returns: ``vector`` Vector with same direction as the input vector, but length 1. Get normalized vector, i.e. a vector with the same direction as the input vector, but with length 1. This does not change the input vector, but creates a new vector. **Example**:: direction = velocity:normalized() .. function:: vector.vector:normalize_inplace() :returns: ``vector`` Itself - the normalized vector Normalize a vector, i.e. make the vector unit length. Great to use on intermediate results. **This modifies the vector. If in doubt, use [``vector:normalized()``](#hump.vectornormalized).** **Example**:: normal = (b - a):perpendicular():normalize_inplace() .. function:: vector.vector:rotated(angle) :param number angle: Rotation angle in radians. :returns: ``vector`` The rotated vector Get a rotated vector. This does not change the input vector, but creates a new vector. **Example**:: -- approximate a circle circle = {} for i = 1,30 do local phi = 2 * math.pi * i / 30 circle[#circle+1] = vector(0,1):rotated(phi) end **Sketch**:: ![Rotated vector sketch](vector-rotated.png) .. function:: vector.vector:rotate_inplace(angle) :param number angle: Rotation angle in radians. :returns: ``vector`` Itself - the rotated vector Rotate a vector in-place. Great to use on intermediate results. **This modifies the vector. If in doubt, use [``vector:rotated()``](#hump.vectorvector:rotated).** **Example**:: -- ongoing rotation spawner.direction:rotate_inplace(dt) .. function:: vector.vector:perpendicular() :returns: ``vector`` A vector perpendicular to the input vector Quick rotation by 90°. Creates a new vector. The same (but faster) as ``vec:rotate(math.pi/2)``. **Example**:: normal = (b - a):perpendicular():normalize_inplace() **Sketch**:: ![Perpendiculat vector sketch](vector-perpendicular.png) .. function:: vector.vector:projectOn(v) :param vector v: The vector to project on. :returns: ``vector`` The projected vector. Project vector onto another vector (see sketch). **Example**:: velocity_component = velocity:projectOn(axis) **Sketch**:: ![Projected vector sketch](vector-projectOn.png) .. function:: vector.vector:mirrorOn(v) :param vector v: The vector to mirror on. :returns: ``vector`` The mirrored vector. Mirrors vector on the axis defined by the other vector. **Example**:: deflected_velocity = ball.velocity:mirrorOn(surface_normal) **Sketch**:: ![Mirrored vector sketch](vector-mirrorOn.png) .. function:: vector.vector:cross(other) :param vector other: Vector to compute the cross product with. :returns: ``number`` Cross product of both vectors. Get cross product of both vectors. Equals the area of the parallelogram spanned by both vectors. **Example**:: parallelogram_area = a:cross(b) .. function:: vector.vector:angleTo(other) :param vector other (optional): Vector to measure the angle to. :returns: ``number`` Angle in radians. Measures the angle between two vectors. If ``other`` is omitted it defaults to the vector ``(0,0)``, i.e. the function returns the angle to the coordinate system. **Example**:: lean = self.upvector:angleTo(vector(0,1)) if lean > .1 then self:fallOver() end