On this page
vmath
Functions for mathematical operations on vectors, matrices and quaternions.
- The vector types (
vmath.vector3andvmath.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 andvmath.vector4values. - 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>): Vectorvmath.vector3(): Vector3vmath.vector3(n: number): Vector3vmath.vector3(v1: Vector3): Vector3vmath.vector3(x: number, y: number, z: number): Vector3vmath.vector4(): Vector4vmath.vector4(n: number): Vector4vmath.vector4(v1: Vector4): Vector4vmath.vector4(x: number, y: number, z: number, w: number): Vector4vmath.quat(): Quaternionvmath.quat(q1: Quaternion): Quaternionvmath.quat(x: number, y: number, z: number, w: number): Quaternionvmath.quat_from_to(v1: Vector3, v2: Vector3): Quaternionvmath.quat_axis_angle(v: Vector3, angle: number): Quaternionvmath.quat_basis(x: Vector3, y: Vector3, z: Vector3): Quaternionvmath.quat_rotation_x(angle: number): Quaternionvmath.quat_rotation_y(angle: number): Quaternionvmath.quat_rotation_z(angle: number): Quaternionvmath.matrix4(): Matrix4vmath.matrix4(m1: Matrix4): Matrix4vmath.matrix4_frustum(left: number, right: number, bottom: number, top: number, near: number, far: number): Matrix4vmath.matrix4_look_at(eye: Vector3, look_at: Vector3, up: Vector3): Matrix4vmath.matrix4_orthographic(left: number, right: number, bottom: number, top: number, near: number, far: number): Matrix4vmath.matrix4_perspective(fov: number, aspect: number, near: number, far: number): Matrix4vmath.matrix4_quat(q: Quaternion): Matrix4vmath.matrix4_axis_angle(v: Vector3, angle: number): Matrix4vmath.matrix4_rotation_x(angle: number): Matrix4vmath.matrix4_rotation_y(angle: number): Matrix4vmath.matrix4_rotation_z(angle: number): Matrix4vmath.matrix4_translation(position: Vector3 | Vector4): Matrix4vmath.inv(m1: Matrix4): Matrix4vmath.ortho_inv(m1: Matrix4): Matrix4vmath.dot(v1: Vector3 | Vector4, v2: Vector3 | Vector4): numbervmath.length_sqr(v: Vector3 | Vector4 | Quaternion): numbervmath.length(v: Vector3 | Vector4 | Quaternion): numbervmath.normalize<T extends Vector3 | Vector4 | Quaternion>(v1: T): Tvmath.cross(v1: Vector3, v2: Vector3): Vector3vmath.lerp<T extends Vector3 | Vector4>(t: number, v1: T, v2: T): Tvmath.lerp(t: number, q1: Quaternion, q2: Quaternion): Quaternionvmath.lerp(t: number, n1: number, n2: number): numbervmath.slerp<T extends Vector3 | Vector4>(t: number, v1: T, v2: T): Tvmath.slerp(t: number, q1: Quaternion, q2: Quaternion): Quaternionvmath.conj(q1: Quaternion): Quaternionvmath.rotate(q: Quaternion, v1: Vector3): Vector3vmath.project(v1: Vector3, v2: Vector3): numbervmath.mul_per_elem<T extends Vector3 | Vector4>(v1: T, v2: T): Tvmath.quat_matrix4(matrix: Matrix4): Quaternionvmath.matrix4_compose(translation: Vector3 | Vector4, rotation: Quaternion, scale: Vector3): Matrix4vmath.matrix4_scale(scale: Vector3): Matrix4vmath.matrix4_scale(scale: number): Matrix4vmath.matrix4_scale(scale_x: number, scale_y: number, scale_z: number): Matrix4vmath.clamp<T extends number | Vector3 | Vector4>(value: T, min: number | T, max: number | T): Tvmath.quat_to_euler(q: Quaternion): number, number, numbervmath.euler_to_quat(x: number | Vector3, y: number, z: number): Quaternion
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 coordinatey:number— y coordinatez: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 coordinatey:number— y coordinatez:number— z coordinatew: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 coordinatey:number— y coordinatez:number— z coordinatew: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 rotationv2: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— axisangle: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 vectory:Vector3— y base vectorz: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 planeright:number— coordinate for right clipping planebottom:number— coordinate for bottom clipping planetop:number— coordinate for top clipping planenear:number— coordinate for near clipping planefar: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 positionlook_at:Vector3— look-at positionup: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 planeright:number— coordinate for right clipping planebottom:number— coordinate for bottom clipping planetop:number— coordinate for top clipping planenear:number— coordinate for near clipping planefar: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 radiansaspect:number— aspect rationear:number— coordinate for near clipping planefar: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— axisangle: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 ⋅ Q = |P| |Q| cos θ
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 vectorv2: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 vectorv2: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-1v1:Vector3 | Vector4— vector to lerp fromv2: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-1v1:Vector3 | Vector4— vector to slerp fromv2: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— quaternionv1: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 θ / |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 secondv2: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 vectorv2: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— translationrotation:Quaternion— rotationscale: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 axisscale_y:number— sclae along Y axisscale_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 valuesmin:number | Vector3 | Vector4— Min value(s) bordermax: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 degreesy:number— euler angle y in degreesz: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 degreesy:number— rotation around y-axis in degreesz:number— rotation around z-axis in degrees
Returns
q:Quaternion— quaternion describing an equivalent rotation (231 (YZX) rotation sequence)