« Back to search

Mod

Vector3

by giga-turbo · score 9.3 · license: GPL-3.0-only

Vector3

Download latest release

3D Vector class with meta functions

library

Usage

  1. Make your mod depends on vector3 ;
  2. Create vectors with vector3(x, y, z) ;
  3. See available methods below

All functions create new vectors so that the original vector is not modified. All the functions return the new vector so that operations can be chained easily.

Example:

u = vector3(1, 2, 3)
v = vector3(4, 5, 6)
w = (5 * u + u:dot(v) * u:cross(v:scale(5))):norm()

Constructors

vector3(x, y, z)

Creates a new vector with components x, y and z. Components defaults to zero.

v0 = vector3() -- (0,0,0)
v1 = vector3(1,2,3) -- (1,2,3)

vector3.fromSpherical(r, theta, phi)

Creates a new vector from spherical coordinates. theta is the polar angle (from the upwards y axis), phi the azimut (counting clockwise around y, starting from x), and r the radius. Default values are r=1, theta=pi/2, phi=0.

v2 = vector3.fromSpherical(10, math.pi / 2, math.pi) -- (-10, 0, 0)

vector3.fromCylindrical(r, phi, y)

Creates a new vector from cylindrical coordinates. r is the radius, phi is the azimut angle (counting clockwise around y, starting from x) and y the height. Default values are r=1, phi=0 and y=1.

v21 = vector3.fromCylindrical(10, math.pi / 2, 5) -- (0, 5, 10)

vector3.fromPolar(r, phi)

Creates a new vector from polar coordinates. r is the radius and phi the angle (counting clockwise around y, starting from x). Default values are r=1 and phi=0.

v22 = vector3.fromPolar(6, - math.pi / 2) -- (0, 0, -6)

vector3.srandom(a, b)

Creates a vector drawn uniformly from a ball centred on the origin. With no argument the ball has radius 1, with one argument it has that radius, and with both it is the spherical shell between radii a and b, given in either order. a == b gives a point on the sphere of that radius. The distribution is uniform by volume, so the radius is not uniform: points are as dense near the origin as they are near the surface.

v3 = vector3.srandom()          -- uniform in the unit ball
v31 = vector3.srandom(10)       -- uniform in the ball of radius 10
v32 = vector3.srandom(9, 10)    -- uniform in the shell between 9 and 10
v33 = vector3.srandom(10, 10)   -- uniform on the sphere of radius 10

vector3.crandom(a, b, c, d)

Creates a vector drawn uniformly from a cylinder whose axis is y. a and b give the radius in the xz plane exactly as in vector3.srandom, but over a disk or an annulus. c and d give the height: neither puts y in [0, 1), one puts it in [0, c) or [0, d), and both put it in [c, d).

v34 = vector3.crandom(0, 10, 5, 15)

vector3.prandom(a, b)

Creates a vector drawn uniformly from a disk centred on the origin and lying in the y = 0 plane. a and b are as in vector3.srandom, over a disk or an annulus, and a == b gives a point on the circle of that radius. The distribution is uniform by area.

v35 = vector3.prandom()         -- uniform in the unit disk
v36 = vector3.prandom(10, 10)   -- uniform on the circle of radius 10

Constants

The constants are read-only. One table per name is shared by every mod in the process, so writing to one raises an error instead of changing it for everybody.

vector3.zero = vector3(0, 0, 0)
vector3.one = vector3(1, 1, 1)
vector3.x = vector3(1, 0, 0)
vector3.y = vector3(0, 1, 0)
vector3.z = vector3(0, 0, 1)
vector3.xy = vector3(1, 1, 0)
vector3.yz = vector3(0, 1, 1)
vector3.xz = vector3(1, 0, 1)
vector3.nx = -vector3(1, 0, 0)
vector3.ny = -vector3(0, 1, 0)
vector3.nz = -vector3(0, 0, 1)
vector3.nxy = -vector3(1, 1, 0)
vector3.nyz = -vector3(0, 1, 1)
vector3.nxz = -vector3(1, 0, 1)

A constant reads and computes like any other vector: components, methods, operators, comparison and print all work, and every one of them returns an ordinary writable vector. The constant itself is not a plain table, though, so pairs, rawget, table.copy and minetest.serialize see it as empty. Take a writable copy with vector3(vector3.zero) or vector3.zero:clone().

Meta functions

print

Allows to print a vector.

print(v1)

concatenation

Allows to create strings from vector concatenation.

print(v1 .. v2 .. v3)

negative

Returns the opposite vector.

v5 = -v1

equality

Return true if two vectors have their components equals

v1 == v2

addition

Return the sum of two vectors component wise. If one argument is a number then this number is added to each component of the vector.

v1 + v2
v1 + 10

subtraction

Return the difference of two vectors component wise. If one argument is a number then this number is subtracted to each component of the vector.

v1 - v2
v1 - 1

multiplication

Return the product of two vectors component wise. If one argument is a number then each component of the vector is multiplied by this number.

v1 * v2
v1 * 10

division

Return the division of two vectors component wise. If one argument is a number then each component of the vector is divided by this number.

v1 / v3
v1 / 10

Functions

clone()

Return a new vector which is a copy of the initial vector.

v4 = v1:clone()

length()

Returns the magnitude of the vector.

v3:length()

norm()

Return the corresponding normalized vector (with magnitude one).

v3:norm()

scale(mag)

Return a new vector which is scaled to magnitude mag

v1:scale(10)

limit(max)

Returns a new vector which is scaled to magnitude max if its magnitude if greater than max.

vector3(10, 20, 30):limit(5)
vector3(1, 2, 3):limit(5)

floor()

Return a new vector with the components floored.

v3:floor()

round(dec)

Return a new vector with the components rounded to the closest integer, or to dec decimals when it is given. A half always rounds up, and a negative dec rounds to tens, hundreds and so on. Beyond about 15 decimals the result is not meaningful.

v3:round()      -- to the closest integer
v3:round(2)     -- to two decimals
v3:round(-2)    -- to the closest hundred

set(x, y, z)

Return a new vector with components x,y and z. If a parameter is nil then the corresponding component is unchanged.

v1:set(4, nil, 7)

offset(a, b, c)

Return a new vector with components x, y, z offset by a, b and c. If a parameter is nil the corresponding component is unchanged.

v2:offset(-1, 3, 2)

apply(f)

Return a new vector with the function f applied to its components.

v2:apply(function(x) return x * x end)

dist(b)

Returns the distance between the current vector and b (as if they were representing points).

v1:dist(v2)

dot(b)

Returns the dot product of the current vector and b.

v1:dot(v2)

cross(b)

Returns a vector which is the cross product of the current vector and b.

v1:cross(v2)

rotate_around(axis, angle)

Returns a new vector which is the current vector rotated around axis with angle.

axis = vector3(0, 1, 0)
v2:rotate_around(axis, math.pi)

unpack()

Returns the unpacked components of the current vector.

x, y, z = v1:unpack()
print(x)
print(y)
print(z)