# 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.
• `vector.to_string(v)`:
• Returns a string of the form `"(x, y, z)"`.
• `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)`.
• `vector.distance(p1, p2)`:
• Returns zero or a positive number, the distance between `p1` and `p2`.
• `vector.length(v)`:
• Returns zero or a positive number, the length of vector `v`.
• `vector.normalize(v)`:
• Returns a vector of length 1 with direction of vector `v`.
• If `v` has zero length, returns `(0, 0, 0)`.
• `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.
• `vector.equals(v1, v2)`:
• Returns a boolean, `true` if the vectors are identical.
• `vector.sort(v1, v2)`:
• Returns in order minp, maxp vectors of the cuboid defined by `v1`, `v2`.
• `vector.angle(v1, v2)`:
• Returns the angle between `v1` and `v2` in radians.
• `vector.dot(v1, v2)`:
• Returns the dot product of `v1` and `v2`.
• `vector.cross(v1, v2)`:
• Returns the cross product of `v1` and `v2`.
• `vector.offset(v, x, y, z)`:
• Returns the sum of the vectors `v` and `(x, y, z)`.
• `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}`.

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 = , y = , z = }) where pitch, yaw and roll are angles in radians.

• `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`.
• `vector.rotate_around_axis(v1, v2, a)`:
• Returns `v1` rotated around axis `v2` by `a` radians according to the right hand rule.
• `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.