# Spatial Vectors¶

A spatial vector is similar to a position, but instead using
absolute world coordinates, it uses *relative* coordinates, relative to
no particular point.

Internally, it is implemented as a table with the 3 fields
`x`

, `y`

and `z`

. Example: `{x = 0, y = 1, z = 0}`

.
However, one should *never* create a vector manually as above, such misbehavior
is deprecated. The vector helpers set a metatable for the created vectors which
allows indexing with numbers, calling functions directly on vectors and using
operators (like `+`

). Furthermore, the internal implementation might change in
the future.
Old code might still use vectors without metatables, be aware of this!

All these forms of addressing a vector `v`

are valid:
`v[1]`

, `v[3]`

, `v.x`

, `v[1] = 42`

, `v.y = 13`

Where `v`

is a vector and `foo`

stands for any function name, `v:foo(...)`

does
the same as `vector.foo(v, ...)`

, apart from deprecated functionality.

The metatable that is used for vectors can be accessed via `vector.metatable`

.
Do not modify it!

All `vector.*`

functions allow vectors `{x = X, y = Y, z = Z}`

without metatables.
Returned vectors always have a metatable set.

For the following functions, `v`

, `v1`

, `v2`

are vectors,
`p1`

, `p2`

are positions,
`s`

is a scalar (a number),
vectors are written like this: `(x, y, z)`

:

`vector.new([a[, b, c]])`

:- Returns a vector.
- A copy of
`a`

if`a`

is a vector. `(a, b, c)`

, if all of`a`

,`b`

,`c`

are defined numbers.`(0, 0, 0)`

, if no arguments are given.

`vector.from_string(s[, init])`

:- Returns
`v, np`

, where`v`

is a vector read from the given string`s`

and`np`

is the next position in the string after the vector. - Returns
`nil`

on failure. `s`

: Has to begin with a substring of the form`"(x, y, z)"`

. Additional spaces, leaving away commas and adding an additional comma to the end is allowed.`init`

: If given starts looking for the vector at this string index.

- Returns
`vector.to_string(v)`

:- Returns a string of the form
`"(x, y, z)"`

.

- Returns a string of the form
`vector.direction(p1, p2)`

:- Returns a vector of length 1 with direction
`p1`

to`p2`

. - If
`p1`

and`p2`

are identical, returns`(0, 0, 0)`

.

- Returns a vector of length 1 with direction
`vector.distance(p1, p2)`

:- Returns zero or a positive number, the distance between
`p1`

and`p2`

.

- Returns zero or a positive number, the distance between
`vector.length(v)`

:- Returns zero or a positive number, the length of vector
`v`

.

- Returns zero or a positive number, the length of vector
`vector.normalize(v)`

:- Returns a vector of length 1 with direction of vector
`v`

. - If
`v`

has zero length, returns`(0, 0, 0)`

.

- Returns a vector of length 1 with direction of vector
`vector.floor(v)`

:- Returns a vector, each dimension rounded down.

`vector.round(v)`

:- Returns a vector, each dimension rounded to nearest integer.
- At a multiple of 0.5, rounds away from zero.

`vector.apply(v, func)`

:- Returns a vector where the function
`func`

has been applied to each component.

- Returns a vector where the function
`vector.equals(v1, v2)`

:- Returns a boolean,
`true`

if the vectors are identical.

- Returns a boolean,
`vector.sort(v1, v2)`

:- Returns in order minp, maxp vectors of the cuboid defined by
`v1`

,`v2`

.

- Returns in order minp, maxp vectors of the cuboid defined by
`vector.angle(v1, v2)`

:- Returns the angle between
`v1`

and`v2`

in radians.

- Returns the angle between
`vector.dot(v1, v2)`

:- Returns the dot product of
`v1`

and`v2`

.

- Returns the dot product of
`vector.cross(v1, v2)`

:- Returns the cross product of
`v1`

and`v2`

.

- Returns the cross product of
`vector.offset(v, x, y, z)`

:- Returns the sum of the vectors
`v`

and`(x, y, z)`

.

- Returns the sum of the vectors
`vector.check()`

:- Returns a boolean value indicating whether
`v`

is a real vector, eg. created by a`vector.*`

function. - Returns
`false`

for anything else, including tables like`{x=3,y=1,z=4}`

.

- Returns a boolean value indicating whether

For the following functions `x`

can be either a vector or a number:

`vector.add(v, x)`

:- Returns a vector.
- If
`x`

is a vector: Returns the sum of`v`

and`x`

. - If
`x`

is a number: Adds`x`

to each component of`v`

.

`vector.subtract(v, x)`

:- Returns a vector.
- If
`x`

is a vector: Returns the difference of`v`

subtracted by`x`

. - If
`x`

is a number: Subtracts`x`

from each component of`v`

.

`vector.multiply(v, s)`

:- Returns a scaled vector.
- Deprecated: If
`s`

is a vector: Returns the Schur product.

`vector.divide(v, s)`

:- Returns a scaled vector.
- Deprecated: If
`s`

is a vector: Returns the Schur quotient.

Operators can be used if all of the involved vectors have metatables:
* `v1 == v2`

:
* Returns whether `v1`

and `v2`

are identical.
* `-v`

:
* Returns the additive inverse of v.
* `v1 + v2`

:
* Returns the sum of both vectors.
* Note: `+`

can not be used together with scalars.
* `v1 - v2`

:
* Returns the difference of `v1`

subtracted by `v2`

.
* Note: `-`

can not be used together with scalars.
* `v * s`

or `s * v`

:
* Returns `v`

scaled by `s`

.
* `v / s`

:
* Returns `v`

scaled by `1 / s`

.

For the following functions `a`

is an angle in radians and `r`

is a rotation
vector ({x =

`vector.rotate(v, r)`

:- Applies the rotation
`r`

to`v`

and returns the result. `vector.rotate(vector.new(0, 0, 1), r)`

and`vector.rotate(vector.new(0, 1, 0), r)`

return vectors pointing forward and up relative to an entity's rotation`r`

.

- Applies the rotation
`vector.rotate_around_axis(v1, v2, a)`

:- Returns
`v1`

rotated around axis`v2`

by`a`

radians according to the right hand rule.

- Returns
`vector.dir_to_rotation(direction[, up])`

:- Returns a rotation vector for
`direction`

pointing forward using`up`

as the up vector. - If
`up`

is omitted, the roll of the returned vector defaults to zero. - Otherwise
`direction`

and`up`

need to be vectors in a 90 degree angle to each other.

- Returns a rotation vector for