On this page

vmath

Functions for mathematical operations on vectors, matrices and quaternions.

  • The vector types (vmath.vector3 and vmath.vector4) supports addition and subtraction with vectors of the same type. Vectors can be negated and multiplied (scaled) or divided by numbers.
  • The quaternion type (vmath.quat) supports multiplication with other quaternions.
  • The matrix type (vmath.matrix4) can be multiplied with numbers, other matrices and vmath.vector4 values.
  • All types performs equality comparison by each component value.

The following components are available for the various types:

vector3 : x, y and z. Example: v.y

vector4 : x, y, z, and w. Example: v.w

quaternion : x, y, z, and w. Example: q.w

matrix4 : m00 to m33 where the first number is the row (starting from 0) and the second number is the column. Columns can be accessed with c0 to c3, returning a vector4. Example: m.m21 which is equal to m.c1.z

vector : indexed by number 1 to the vector length. Example: v[3]

Functions

vmath.vector(t: Record<string | number, unknown>): Vector

Creates a vector of arbitrary size. The vector is initialized with numeric values from a table. The table values are converted to floating point values. If a value cannot be converted, a 0 is stored in that value position in the vector.

// How to create a vector with custom data to be used for animation easing:
const values = [0, 0.5, 0];
const vec = vmath.vector(values);
print(vec); // => vmath.vector (size: 3)
print(vec[2]); // => 0.5

Parameters

  • t: Record<string | number, unknown> — table of numbers

Returns

  • v: Vector — new vector

vmath.vector3(): Vector3

Creates a new zero vector with all components set to 0.

const vec = vmath.vector3();
pprint(vec); // => vmath.vector3(0, 0, 0)
print(vec.x); // => 0

Returns

  • v: Vector3 — new zero vector

vmath.vector3(n: number): Vector3

Creates a new vector with all components set to the supplied scalar value.

const vec = vmath.vector3(1.0);
print(vec); // => vmath.vector3(1, 1, 1)
print(vec.x); // => 1

Parameters

  • n: number — scalar value to splat

Returns

  • v: Vector3 — new vector

vmath.vector3(v1: Vector3): Vector3

Creates a new vector with all components set to the corresponding values from the supplied vector. I.e. This function creates a copy of the given vector.

const vec1 = vmath.vector3(1.0);
const vec2 = vmath.vector3(vec1);
if (vec1 === vec2) {
  // yes, they are equal
  print(vec2); // => vmath.vector3(1, 1, 1)
}

Parameters

  • v1: Vector3 — existing vector

Returns

  • v: Vector3 — new vector

vmath.vector3(x: number, y: number, z: number): Vector3

Creates a new vector with the components set to the supplied values.

const vec = vmath.vector3(1.0, 2.0, 3.0);
print(vec); // => vmath.vector3(1, 2, 3)
print(vec.unm()); // => vmath.vector3(-1, -2, -3)
print(vec.mul(2)); // => vmath.vector3(2, 4, 6)
print(vec.add(vmath.vector3(2.0))); // => vmath.vector3(3, 4, 5)
print(vec.sub(vmath.vector3(2.0))); // => vmath.vector3(-1, 0, 1)

Parameters

  • x: number — x coordinate
  • y: number — y coordinate
  • z: number — z coordinate

Returns

  • v: Vector3 — new vector

vmath.vector4(): Vector4

Creates a new zero vector with all components set to 0.

const vec = vmath.vector4();
print(vec); // => vmath.vector4(0, 0, 0, 0)
print(vec.w); // => 0

Returns

  • v: Vector4 — new zero vector

vmath.vector4(n: number): Vector4

Creates a new vector with all components set to the supplied scalar value.

const vec = vmath.vector4(1.0);
print(vec); // => vmath.vector4(1, 1, 1, 1)
print(vec.w); // => 1

Parameters

  • n: number — scalar value to splat

Returns

  • v: Vector4 — new vector

vmath.vector4(v1: Vector4): Vector4

Creates a new vector with all components set to the corresponding values from the supplied vector. I.e. This function creates a copy of the given vector.

const vec1 = vmath.vector4(1.0);
const vec2 = vmath.vector4(vec1);
if (vec1 === vec2) {
  // yes, they are equal
  print(vec2); // => vmath.vector4(1, 1, 1, 1)
}

Parameters

  • v1: Vector4 — existing vector

Returns

  • v: Vector4 — new vector

vmath.vector4(x: number, y: number, z: number, w: number): Vector4

Creates a new vector with the components set to the supplied values.

const vec = vmath.vector4(1.0, 2.0, 3.0, 4.0);
print(vec); // => vmath.vector4(1, 2, 3, 4)
print(vec.unm()); // => vmath.vector4(-1, -2, -3, -4)
print(vec.mul(2)); // => vmath.vector4(2, 4, 6, 8)
print(vec.add(vmath.vector4(2.0))); // => vmath.vector4(3, 4, 5, 6)
print(vec.sub(vmath.vector4(2.0))); // => vmath.vector4(-1, 0, 1, 2)

Parameters

  • x: number — x coordinate
  • y: number — y coordinate
  • z: number — z coordinate
  • w: number — w coordinate

Returns

  • v: Vector4 — new vector

vmath.quat(): Quaternion

Creates a new identity quaternion. The identity quaternion is equal to: vmath.quat(0, 0, 0, 1)

const quat = vmath.quat();
print(quat); // => vmath.quat(0, 0, 0, 1)
print(quat.w); // => 1

Returns

  • q: Quaternion — new identity quaternion

vmath.quat(q1: Quaternion): Quaternion

Creates a new quaternion with all components set to the corresponding values from the supplied quaternion. I.e. This function creates a copy of the given quaternion.

const quat1 = vmath.quat(1, 2, 3, 4);
const quat2 = vmath.quat(quat1);
if (quat1 === quat2) {
  // yes, they are equal
  print(quat2); // => vmath.quat(1, 2, 3, 4)
}

Parameters

  • q1: Quaternion — existing quaternion

Returns

  • q: Quaternion — new quaternion

vmath.quat(x: number, y: number, z: number, w: number): Quaternion

Creates a new quaternion with the components set according to the supplied parameter values.

const quat = vmath.quat(1, 2, 3, 4);
print(quat); // => vmath.quat(1, 2, 3, 4)

Parameters

  • x: number — x coordinate
  • y: number — y coordinate
  • z: number — z coordinate
  • w: number — w coordinate

Returns

  • q: Quaternion — new quaternion

vmath.quat_from_to(v1: Vector3, v2: Vector3): Quaternion

The resulting quaternion describes the rotation that, if applied to the first vector, would rotate the first vector to the second. The two vectors must be unit vectors (of length 1). The result is undefined if the two vectors point in opposite directions

const v1 = vmath.vector3(1, 0, 0);
const v2 = vmath.vector3(0, 1, 0);
const rot = vmath.quat_from_to(v1, v2);
print(vmath.rotate(rot, v1)); // => vmath.vector3(0, 0.99999994039536, 0)

Parameters

  • v1: Vector3 — first unit vector, before rotation
  • v2: Vector3 — second unit vector, after rotation

Returns

  • q: Quaternion — quaternion representing the rotation from first to second vector

vmath.quat_axis_angle(v: Vector3, angle: number): Quaternion

The resulting quaternion describes a rotation of angle radians around the axis described by the unit vector v.

const axis = vmath.vector3(1, 0, 0);
const rot = vmath.quat_axis_angle(axis, 3.141592653);
const vec = vmath.vector3(1, 1, 0);
print(vmath.rotate(rot, vec)); // => vmath.vector3(1, -1, -8.7422776573476e-08)

Parameters

  • v: Vector3 — axis
  • angle: number — angle

Returns

  • q: Quaternion — quaternion representing the axis-angle rotation

vmath.quat_basis(x: Vector3, y: Vector3, z: Vector3): Quaternion

The resulting quaternion describes the rotation from the identity quaternion (no rotation) to the coordinate system as described by the given x, y and z base unit vectors.

// Axis rotated 90 degrees around z.
const rot_x = vmath.vector3(0, -1, 0);
const rot_y = vmath.vector3(1, 0, 0);
const z = vmath.vector3(0, 0, 1);
const rot1 = vmath.quat_basis(rot_x, rot_y, z);
const rot2 = vmath.quat_from_to(vmath.vector3(0, 1, 0), vmath.vector3(1, 0, 0));
if (rot1 === rot2) {
  // These quaternions are equal!
  print(rot2); // => vmath.quat(0, 0, -0.70710676908493, 0.70710676908493)
}

Parameters

  • x: Vector3 — x base vector
  • y: Vector3 — y base vector
  • z: Vector3 — z base vector

Returns

  • q: Quaternion — quaternion representing the rotation of the specified base vectors

vmath.quat_rotation_x(angle: number): Quaternion

The resulting quaternion describes a rotation of angle radians around the x-axis.

const rot = vmath.quat_rotation_x(3.141592653);
const vec = vmath.vector3(1, 1, 0);
print(vmath.rotate(rot, vec)); // => vmath.vector3(1, -1, -8.7422776573476e-08)

Parameters

  • angle: number — angle in radians around x-axis

Returns

  • q: Quaternion — quaternion representing the rotation around the x-axis

vmath.quat_rotation_y(angle: number): Quaternion

The resulting quaternion describes a rotation of angle radians around the y-axis.

const rot = vmath.quat_rotation_y(3.141592653);
const vec = vmath.vector3(1, 1, 0);
print(vmath.rotate(rot, vec)); // => vmath.vector3(-1, 1, 8.7422776573476e-08)

Parameters

  • angle: number — angle in radians around y-axis

Returns

  • q: Quaternion — quaternion representing the rotation around the y-axis

vmath.quat_rotation_z(angle: number): Quaternion

The resulting quaternion describes a rotation of angle radians around the z-axis.

const rot = vmath.quat_rotation_z(3.141592653);
const vec = vmath.vector3(1, 1, 0);
print(vmath.rotate(rot, vec)); // => vmath.vector3(-0.99999988079071, -1, 0)

Parameters

  • angle: number — angle in radians around z-axis

Returns

  • q: Quaternion — quaternion representing the rotation around the z-axis

vmath.matrix4(): Matrix4

The resulting identity matrix describes a transform with no translation or rotation.

const mat = vmath.matrix4();
print(mat); // => vmath.matrix4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
// get column 0:
print(mat.c0); // => vmath.vector4(1, 0, 0, 0)
// get the value in row 3 and column 2:
print(mat.m32); // => 0

Returns

  • m: Matrix4 — identity matrix

vmath.matrix4(m1: Matrix4): Matrix4

Creates a new matrix with all components set to the corresponding values from the supplied matrix. I.e. the function creates a copy of the given matrix.

const mat1 = vmath.matrix4_rotation_x(3.141592653);
const mat2 = vmath.matrix4(mat1);
if (mat1 === mat2) {
  // yes, they are equal
  print(mat2); // => vmath.matrix4(1, 0, 0, 0, 0, -1, 8.7422776573476e-08, 0, 0, -8.7422776573476e-08, -1, 0, 0, 0, 0, 1)
}

Parameters

  • m1: Matrix4 — existing matrix

Returns

  • m: Matrix4 — matrix which is a copy of the specified matrix

vmath.matrix4_frustum(left: number, right: number, bottom: number, top: number, near: number, far: number): Matrix4

Constructs a frustum matrix from the given values. The left, right, top and bottom coordinates of the view cone are expressed as distances from the center of the near clipping plane. The near and far coordinates are expressed as distances from the tip of the view frustum cone.

// Construct a projection frustum with a vertical and horizontal FOV of
// 45 degrees. Useful for rendering a square view.
const proj = vmath.matrix4_frustum(-1, 1, -1, 1, 1, 1000);
render.set_projection(proj);

Parameters

  • left: number — coordinate for left clipping plane
  • right: number — coordinate for right clipping plane
  • bottom: number — coordinate for bottom clipping plane
  • top: number — coordinate for top clipping plane
  • near: number — coordinate for near clipping plane
  • far: number — coordinate for far clipping plane

Returns

  • m: Matrix4 — matrix representing the frustum

vmath.matrix4_look_at(eye: Vector3, look_at: Vector3, up: Vector3): Matrix4

The resulting matrix is created from the supplied look-at parameters. This is useful for constructing a view matrix for a camera or rendering in general.

// Set up a perspective camera at z 100 with 45 degrees (pi/2) FOV, aspect ratio 4:3.
const eye = vmath.vector3(0, 0, 100);
const look_at = vmath.vector3(0, 0, 0);
const up = vmath.vector3(0, 1, 0);
const view = vmath.matrix4_look_at(eye, look_at, up);
render.set_view(view);
const proj = vmath.matrix4_perspective(3.141592 / 2, 4 / 3, 1, 1000);
render.set_projection(proj);

Parameters

  • eye: Vector3 — eye position
  • look_at: Vector3 — look-at position
  • up: Vector3 — up vector

Returns

  • m: Matrix4 — look-at matrix

vmath.matrix4_orthographic(left: number, right: number, bottom: number, top: number, near: number, far: number): Matrix4

Creates an orthographic projection matrix. This is useful to construct a projection matrix for a camera or rendering in general.

// Set up an orthographic projection based on the width and height of the
// game window.
const w = render.get_width();
const h = render.get_height();
const proj = vmath.matrix4_orthographic(-w / 2, w / 2, -h / 2, h / 2, -1000, 1000);
render.set_projection(proj);

Parameters

  • left: number — coordinate for left clipping plane
  • right: number — coordinate for right clipping plane
  • bottom: number — coordinate for bottom clipping plane
  • top: number — coordinate for top clipping plane
  • near: number — coordinate for near clipping plane
  • far: number — coordinate for far clipping plane

Returns

  • m: Matrix4 — orthographic projection matrix

vmath.matrix4_perspective(fov: number, aspect: number, near: number, far: number): Matrix4

Creates a perspective projection matrix. This is useful to construct a projection matrix for a camera or rendering in general.

// Set up a perspective camera at z 100 with 45 degrees (pi/2) FOV, aspect ratio 4:3.
const eye = vmath.vector3(0, 0, 100);
const look_at = vmath.vector3(0, 0, 0);
const up = vmath.vector3(0, 1, 0);
const view = vmath.matrix4_look_at(eye, look_at, up);
render.set_view(view);
const proj = vmath.matrix4_perspective(3.141592 / 2, 4 / 3, 1, 1000);
render.set_projection(proj);

Parameters

  • fov: number — angle of the full vertical field of view in radians
  • aspect: number — aspect ratio
  • near: number — coordinate for near clipping plane
  • far: number — coordinate for far clipping plane

Returns

  • m: Matrix4 — perspective projection matrix

vmath.matrix4_quat(q: Quaternion): Matrix4

The resulting matrix describes the same rotation as the quaternion, but does not have any translation (also like the quaternion).

const vec = vmath.vector4(1, 1, 0, 0);
const quat = vmath.quat_rotation_z(3.141592653);
const mat = vmath.matrix4_quat(quat);
print(mat.mul(vec)); // => vmath.matrix4_frustum(-1, 1, -1, 1, 1, 1000)

Parameters

  • q: Quaternion — quaternion to create matrix from

Returns

  • m: Matrix4 — matrix represented by quaternion

vmath.matrix4_axis_angle(v: Vector3, angle: number): Matrix4

The resulting matrix describes a rotation around the axis by the specified angle.

const vec = vmath.vector4(1, 1, 0, 0);
const axis = vmath.vector3(0, 0, 1); // z-axis
const mat = vmath.matrix4_axis_angle(axis, 3.141592653);
print(mat.mul(vec)); // => vmath.vector4(-0.99999994039536, -1.0000001192093, 0, 0)

Parameters

  • v: Vector3 — axis
  • angle: number — angle in radians

Returns

  • m: Matrix4 — matrix represented by axis and angle

vmath.matrix4_rotation_x(angle: number): Matrix4

The resulting matrix describes a rotation around the x-axis by the specified angle.

const vec = vmath.vector4(1, 1, 0, 0);
const mat = vmath.matrix4_rotation_x(3.141592653);
print(mat.mul(vec)); // => vmath.vector4(1, -1, -8.7422776573476e-08, 0)

Parameters

  • angle: number — angle in radians around x-axis

Returns

  • m: Matrix4 — matrix from rotation around x-axis

vmath.matrix4_rotation_y(angle: number): Matrix4

The resulting matrix describes a rotation around the y-axis by the specified angle.

const vec = vmath.vector4(1, 1, 0, 0);
const mat = vmath.matrix4_rotation_y(3.141592653);
print(mat.mul(vec)); // => vmath.vector4(-1, 1, 8.7422776573476e-08, 0)

Parameters

  • angle: number — angle in radians around y-axis

Returns

  • m: Matrix4 — matrix from rotation around y-axis

vmath.matrix4_rotation_z(angle: number): Matrix4

The resulting matrix describes a rotation around the z-axis by the specified angle.

const vec = vmath.vector4(1, 1, 0, 0);
const mat = vmath.matrix4_rotation_z(3.141592653);
print(mat.mul(vec)); // => vmath.vector4(-0.99999994039536, -1.0000001192093, 0, 0)

Parameters

  • angle: number — angle in radians around z-axis

Returns

  • m: Matrix4 — matrix from rotation around z-axis

vmath.matrix4_translation(position: Vector3 | Vector4): Matrix4

The resulting matrix describes a translation of a point in euclidean space.

// Set camera view from custom view and translation matrices.
const mat_trans = vmath.matrix4_translation(vmath.vector3(0, 10, 100));
const mat_view = vmath.matrix4_rotation_y(-3.141592 / 4);
render.set_view(mat_view.mul(mat_trans));

Parameters

  • position: Vector3 | Vector4 — position vector to create matrix from

Returns

  • m: Matrix4 — matrix from the supplied position vector

vmath.inv(m1: Matrix4): Matrix4

The resulting matrix is the inverse of the supplied matrix. For ortho-normal matrices, e.g. regular object transformation, use vmath.ortho_inv() instead. The specialized inverse for ortho-normalized matrices is much faster than the general inverse.

const mat1 = vmath.matrix4_rotation_z(3.141592653);
const mat2 = vmath.inv(mat1);
// M * inv(M) = identity matrix
print(mat1.mul(mat2)); // => vmath.matrix4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)

Parameters

  • m1: Matrix4 — matrix to invert

Returns

  • m: Matrix4 — inverse of the supplied matrix

vmath.ortho_inv(m1: Matrix4): Matrix4

The resulting matrix is the inverse of the supplied matrix. The supplied matrix has to be an ortho-normal matrix, e.g. describe a regular object transformation. For matrices that are not ortho-normal use the general inverse vmath.inv() instead.

const mat1 = vmath.matrix4_rotation_z(3.141592653);
const mat2 = vmath.ortho_inv(mat1);
// M * inv(M) = identity matrix
print(mat1.mul(mat2)); // => vmath.matrix4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)

Parameters

  • m1: Matrix4 — ortho-normalized matrix to invert

Returns

  • m: Matrix4 — inverse of the supplied matrix

vmath.dot(v1: Vector3 | Vector4, v2: Vector3 | Vector4): number

The returned value is a scalar defined as: P &#x22C5; Q = |P| |Q| cos &#x03B8; where θ is the angle between the vectors P and Q.

  • If the dot product is positive then the angle between the vectors is below 90 degrees.

  • If the dot product is zero the vectors are perpendicular (at right-angles to each other).

  • If the dot product is negative then the angle between the vectors is more than 90 degrees.

if (vmath.dot(vector1, vector2) === 0) {
  // The two vectors are perpendicular (at right-angles to each other)
  // ...
}

Parameters

  • v1: Vector3 | Vector4 — first vector
  • v2: Vector3 | Vector4 — second vector

Returns

  • n: number — dot product

vmath.length_sqr(v: Vector3 | Vector4 | Quaternion): number

Returns the squared length of the supplied vector or quaternion.

if (vmath.length_sqr(vector1) < vmath.length_sqr(vector2)) {
  // Vector 1 has less magnitude than vector 2
  // ...
}

Parameters

  • v: Vector3 | Vector4 | Quaternion — value of which to calculate the squared length

Returns

  • n: number — squared length

vmath.length(v: Vector3 | Vector4 | Quaternion): number

Returns the length of the supplied vector or quaternion. If you are comparing the lengths of vectors or quaternions, you should compare the length squared instead as it is slightly more efficient to calculate (it eliminates a square root calculation).

if (vmath.length(self.velocity) < max_velocity) {
  // The speed (velocity vector) is below max.

  // TODO: max_velocity can be expressed as squared
  // so we can compare with length_sqr() instead.
  // ...
}

Parameters

  • v: Vector3 | Vector4 | Quaternion — value of which to calculate the length

Returns

  • n: number — length

vmath.normalize<T extends Vector3 | Vector4 | Quaternion>(v1: T): T

Normalizes a vector, i.e. returns a new vector with the same direction as the input vector, but with length 1. The length of the vector must be above 0, otherwise a division-by-zero will occur.

const vec = vmath.vector3(1, 2, 3);
const norm_vec = vmath.normalize(vec);
print(norm_vec); // => vmath.vector3(0.26726123690605, 0.5345224738121, 0.80178368091583)
print(vmath.length(norm_vec)); // => 0.99999994039536

Parameters

  • v1: Vector3 | Vector4 | Quaternion — vector to normalize

Returns

  • v: Vector3 | Vector4 | Quaternion — new normalized vector

vmath.cross(v1: Vector3, v2: Vector3): Vector3

Given two linearly independent vectors P and Q, the cross product, P × Q, is a vector that is perpendicular to both P and Q and therefore normal to the plane containing them. If the two vectors have the same direction (or have the exact opposite direction from one another, i.e. are not linearly independent) or if either one has zero length, then their cross product is zero.

const vec1 = vmath.vector3(1, 0, 0);
const vec2 = vmath.vector3(0, 1, 0);
print(vmath.cross(vec1, vec2)); // => vmath.vector3(0, 0, 1)
const vec3 = vmath.vector3(-1, 0, 0);
print(vmath.cross(vec1, vec3)); // => vmath.vector3(0, -0, 0)

Parameters

  • v1: Vector3 — first vector
  • v2: Vector3 — second vector

Returns

  • v: Vector3 — a new vector representing the cross product

vmath.lerp<T extends Vector3 | Vector4>(t: number, v1: T, v2: T): T

Linearly interpolate between two vectors. The function treats the vectors as positions and interpolates between the positions in a straight line. Lerp is useful to describe transitions from one place to another over time. The function does not clamp t between 0 and 1.

export default defineScript({
  init() {
    return { t: 0 };
  },

  update(self, dt) {
    self.t = self.t + dt;
    if (self.t <= 1) {
      const startpos = vmath.vector3(0, 600, 0);
      const endpos = vmath.vector3(600, 0, 0);
      const pos = vmath.lerp(self.t, startpos, endpos);
      go.set_position(pos, "go");
    }
  },
});

Parameters

  • t: number — interpolation parameter, 0-1
  • v1: Vector3 | Vector4 — vector to lerp from
  • v2: Vector3 | Vector4 — vector to lerp to

Returns

  • v: Vector3 | Vector4 — the lerped vector

vmath.lerp(t: number, q1: Quaternion, q2: Quaternion): Quaternion

Linearly interpolate between two quaternions. Linear interpolation of rotations are only useful for small rotations. For interpolations of arbitrary rotations, vmath.slerp yields much better results. The function does not clamp t between 0 and 1.

vmath.lerp(t: number, n1: number, n2: number): number

Linearly interpolate between two values. Lerp is useful to describe transitions from one value to another over time. The function does not clamp t between 0 and 1.

vmath.slerp<T extends Vector3 | Vector4>(t: number, v1: T, v2: T): T

Spherically interpolates between two vectors. The difference to lerp is that slerp treats the vectors as directions instead of positions in space. The direction of the returned vector is interpolated by the angle and the magnitude is interpolated between the magnitudes of the from and to vectors. Slerp is computationally more expensive than lerp. The function does not clamp t between 0 and 1.

export default defineScript({
  init() {
    return { t: 0 };
  },

  update(self, dt) {
    self.t = self.t + dt;
    if (self.t <= 1) {
      const startpos = vmath.vector3(0, 600, 0);
      const endpos = vmath.vector3(600, 0, 0);
      const pos = vmath.slerp(self.t, startpos, endpos);
      go.set_position(pos, "go");
    }
  },
});

Parameters

  • t: number — interpolation parameter, 0-1
  • v1: Vector3 | Vector4 — vector to slerp from
  • v2: Vector3 | Vector4 — vector to slerp to

Returns

  • v: Vector3 | Vector4 — the slerped vector

vmath.slerp(t: number, q1: Quaternion, q2: Quaternion): Quaternion

Slerp travels the torque-minimal path maintaining constant velocity, which means it travels along the straightest path along the rounded surface of a sphere. Slerp is useful for interpolation of rotations. The function does not clamp t between 0 and 1.

vmath.conj(q1: Quaternion): Quaternion

Calculates the conjugate of a quaternion. The result is a quaternion with the same magnitudes but with the sign of the imaginary (vector) parts changed: q* = [w, -v]

const quat = vmath.quat(1, 2, 3, 4);
print(vmath.conj(quat)); // => vmath.quat(-1, -2, -3, 4)

Parameters

  • q1: Quaternion — quaternion of which to calculate the conjugate

Returns

  • q: Quaternion — the conjugate

vmath.rotate(q: Quaternion, v1: Vector3): Vector3

Returns a new vector from the supplied vector that is rotated by the rotation described by the supplied quaternion.

const vec = vmath.vector3(1, 1, 0);
const rot = vmath.quat_rotation_z(3.141592563);
print(vmath.rotate(rot, vec)); // => vmath.vector3(-1.0000002384186, -0.99999988079071, 0)

Parameters

  • q: Quaternion — quaternion
  • v1: Vector3 — vector to rotate

Returns

  • v: Vector3 — the rotated vector

vmath.project(v1: Vector3, v2: Vector3): number

Calculates the extent the projection of the first vector onto the second. The returned value is a scalar p defined as: p = |P| cos &#x03B8; / |Q| where θ is the angle between the vectors P and Q.

const v1 = vmath.vector3(1, 1, 0);
const v2 = vmath.vector3(2, 0, 0);
print(vmath.project(v1, v2)); // => 0.5

Parameters

  • v1: Vector3 — vector to be projected on the second
  • v2: Vector3 — vector onto which the first will be projected, must not have zero length

Returns

  • n: number — the projected extent of the first vector onto the second

vmath.mul_per_elem<T extends Vector3 | Vector4>(v1: T, v2: T): T

Performs an element wise multiplication between two vectors of the same type The returned value is a vector defined as (e.g. for a vector3): v = vmath.mul_per_elem(a, b) = vmath.vector3(a.x * b.x, a.y * b.y, a.z * b.z)

const blend_color = vmath.mul_per_elem(color1, color2);

Parameters

  • v1: Vector3 | Vector4 — first vector
  • v2: Vector3 | Vector4 — second vector

Returns

  • v: Vector3 | Vector4 — multiplied vector

vmath.quat_matrix4(matrix: Matrix4): Quaternion

Creates a new quaternion with the components set according to the supplied parameter values.

Parameters

  • matrix: Matrix4 — source matrix4

Returns

  • q: Quaternion — new quaternion

vmath.matrix4_compose(translation: Vector3 | Vector4, rotation: Quaternion, scale: Vector3): Matrix4

Creates a new matrix constructed from separate translation vector, roation quaternion and scale vector

const translation = vmath.vector3(103, -95, 14);
const quat = vmath.quat(1, 2, 3, 4);
const scale = vmath.vector3(1, 0.5, 0.5);
const result = vmath.matrix4_compose(translation, quat, scale);
print(result); // => vmath.matrix4(-25, -10, 11, 103, 28, -9.5, 2, -95, -10, 10, -4.5, 14, 0, 0, 0, 1)

Parameters

  • translation: Vector3 | Vector4 — translation
  • rotation: Quaternion — rotation
  • scale: Vector3 — scale

Returns

  • matrix: Matrix4 — new matrix4

vmath.matrix4_scale(scale: Vector3): Matrix4

Creates a new matrix constructed from scale vector

const scale = vmath.vector3(1, 0.5, 0.5);
const result = vmath.matrix4_scale(scale);
print(result); // => vmath.matrix4(1, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 1)

Parameters

  • scale: Vector3 — scale

Returns

  • matrix: Matrix4 — new matrix4

vmath.matrix4_scale(scale: number): Matrix4

creates a new matrix4 from uniform scale

const result = vmath.matrix4_scale(0.5);
print(result); // => vmath.matrix4(0.5, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 1)

Parameters

  • scale: number — scale

Returns

  • matrix: Matrix4 — new matrix4

vmath.matrix4_scale(scale_x: number, scale_y: number, scale_z: number): Matrix4

Creates a new matrix4 from three scale components

const result = vmath.matrix4_scale(1, 0.5, 0.5);
print(result); // => vmath.matrix4(1, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 1)

Parameters

  • scale_x: number — scale along X axis
  • scale_y: number — sclae along Y axis
  • scale_z: number — scale along Z asis

Returns

  • matrix: Matrix4 — new matrix4

vmath.clamp<T extends number | Vector3 | Vector4>(value: T, min: number | T, max: number | T): T

Clamp input value to be in range of [min, max]. In case if input value has vector3|vector4 type return new vector3|vector4 with clamped value at every vector's element. Min/max arguments can be vector3|vector4. In that case clamp excuted per every vector's element

const value1 = 56;
print(vmath.clamp(value1, 89, 134)); // => 89
const v2 = vmath.vector3(190, 190, -10);
print(vmath.clamp(v2, -50, 150)); // => vmath.vector3(150, 150, -10)
const v3 = vmath.vector4(30, -30, 45, 1);
print(vmath.clamp(v3, 0, 20)); // => vmath.vector4(20, 0, 20, 1)

const min_v = vmath.vector4(0, -10, -10, 1);
print(vmath.clamp(v3, min_v, 20)); // => vmath.vector4(20, -10, 20, 1)

Parameters

  • value: number | Vector3 | Vector4 — Input value or vector of values
  • min: number | Vector3 | Vector4 — Min value(s) border
  • max: number | Vector3 | Vector4 — Max value(s) border

Returns

  • clamped_value: number | Vector3 | Vector4 — Clamped value or vector

vmath.quat_to_euler(q: Quaternion): number, number, number

Converts a quaternion into euler angles (r0, r1, r2), based on YZX rotation order. To handle gimbal lock (singularity at r1 ~ +/- 90 degrees), the cut off is at r0 = +/- 88.85 degrees, which snaps to +/- 90. The provided quaternion is expected to be normalized. The error is guaranteed to be less than +/- 0.02 degrees

const q = vmath.quat_rotation_z(math.rad(90));
print(vmath.quat_to_euler(q)); // => 0 0 90

const q2 = vmath.quat_rotation_y(math.rad(45)).mul(vmath.quat_rotation_z(math.rad(90)));
const [ex, ey, ez] = vmath.quat_to_euler(q2);
const v = vmath.vector3(ex, ey, ez);
print(v); // => vmath.vector3(0, 45, 90)

Parameters

  • q: Quaternion — source quaternion

Returns

  • x: number — euler angle x in degrees
  • y: number — euler angle y in degrees
  • z: number — euler angle z in degrees

vmath.euler_to_quat(x: number | Vector3, y: number, z: number): Quaternion

Converts euler angles (x, y, z) in degrees into a quaternion The error is guaranteed to be less than 0.001. If the first argument is vector3, its values are used as x, y, z angles.

const q = vmath.euler_to_quat(0, 45, 90);
print(q); // => vmath.quat(0.27059805393219, 0.27059805393219, 0.65328145027161, 0.65328145027161)

const v = vmath.vector3(0, 0, 90);
print(vmath.euler_to_quat(v)); // => vmath.quat(0, 0, 0.70710676908493, 0.70710676908493)

Parameters

  • x: number | Vector3 — rotation around x-axis in degrees or vector3 with euler angles in degrees
  • y: number — rotation around y-axis in degrees
  • z: number — rotation around z-axis in degrees

Returns

  • q: Quaternion — quaternion describing an equivalent rotation (231 (YZX) rotation sequence)