H3DU’s Math Functions

Back to documentation index.

The HTML 3D library includes a collection of math functions for working with vectors, matrices, and quaternions.

Here is an overview of these data types.

Contents

Vectors

A vector is a line segment pointing in a certain direction in space and having a certain length and an unspecified starting point. A particular vector can instead be treated as describing a position (by pointing to that position from an origin (0,0,0)), or a color.

In MathUtil, vectors are stored in arrays of numbers (usually three or four numbers), and functions dealing with vectors begin with “vec”.

If a 4-element vector describes a position or direction, the elements are given as X, Y, Z, and W, in that order.

If a 4-element vector describes a color, the elements are given as red, green, blue, and alpha, in that order (where each element ranges from 0-1).

If a 3D direction is used in a 4-element vector function (one beginning with “vec4”), use 0 as the fourth element. If a 3D position (point) is used in a 4-element vector function, the fourth element is generally 1. (If the fourth element is anything other than 0, the vector is in homogeneous coordinates, where the 3D position equals the first three elements divided by the fourth.)

Unit Vectors

A unit vector is a vector with a length of 1. (A vector’s length, or norm, is the square root of the sum of the squares of its components.) A vector can be “normalized” to a unit vector by dividing each of its components by its length (doing so won’t change the vector’s direction).

The following functions normalize vectors and find their length.

Note that due to rounding error, normalizing a vector with a MathUtil method might not necessarily result in a vector with a length of 1.

Matrices

A matrix is a rectangular array that can describe a transformation from one coordinate system to another. Transformations include translation (shifting), scaling, and rotation. Functions dealing with matrices begin with “mat”. A 3x3 or 4x4 matrix has 9 or 16 elements, respectively. For more details, see the Matrix Details tutorial.

Translation

A translation is a shifting of an object’s position.

To create a translation matrix, use MathUtil.mat4translated(), and specify the X-offset, the Y-offset, and the Z-offset. For example, an X-offset of 1 moves an object 1 unit to the right, and a Y offset of -1 moves it 1 unit down.

To multiply an existing matrix by a translation, use MathUtil.mat4translate(). This will put the translation before the other transformations.

Scaling

Scaling changes an object’s size.

To create a scaling matrix, use MathUtil.mat4scaled(), and specify the scaling factors for the X, Y, and Z axis. Each point is multiplied by the scaling factors to change the object’s size. For example, a Y-factor of 2 doubles an object’s height.

To multiply an existing matrix by a scaling, use MathUtil.mat4scale(). This will put the scaling before the other transformations.

Rotation

Rotation changes an object’s orientation.

To create a rotation matrix, use MathUtil.mat4rotated(), and specify the angle (in degrees) to rotate, and the axis of rotation. For example:

When describing an axis of rotation, [1, 0, 0] is the X axis, [0, 1, 0] is the Y axis, and [0, 0, 1] is the Z axis.

To multiply an existing matrix by a rotation, use MathUtil.mat4rotate(). This will put the rotation before the other transformations.

Combining Transforms

The order in which you do transforms is important. In general, scaling then translating is not the same as translating then scaling. Assuming your geometry is centered at the origin (0, 0, 0), you should create a transformation in this order:

This way, the scalings and rotations will affect the object while it’s still centered, and before the translations (shifts) take place.

You can also multiply transforms using MathUtil.mat4multiply(). This takes two matrices and returns one combined matrix. The combined matrix will have the effect of doing the second matrix’s transform, then the first matrix’s transform.

Describing Rotations

Rotations in 3D space can be described in many ways, including quaternions, Tait-Bryan angles, and an angle and axis.

Axis of Rotation

A rotation of vectors or points can be described using an angle and an axis of rotation, for example, in the MathUtil.mat4rotate method.

An axis of rotation is a vector pointing in a certain direction. When a point (or vector) is rotated at any angle around this axis, the new point (or vector) will lie on the same plane as the previous point. The axis of rotation describes a vector that is perpendicular to that plane’s surface (the plane’s normal). Here are examples of an axis of rotation.

While the axis of rotation points backward from the “eye”, if the angle’s value is positive and the coordinate system is…

While the axis of rotation points backward from the “eye”, if the angle’s value is negative, then the angle runs in the opposite direction.

Vectors that point in the same direction (for example, vectors (1, 0, 0) and (2, 0, 0)) describe the same axis of rotation.

Unless stated otherwise, an axis of rotation passed to a MathUtil method need not be a unit vector.

Quaternions

A quaternion is a 4-element vector that can describe a 3D rotation. Functions dealing with quaternions begin with “quat”.

Generating Quaternions

Functions that generate quaternions include:

Using Quaternions

For best results when using quaternions:

Multiplying Quaternions

When two quaternions are multiplied (for example, with {@MathUtil.quatMultiply}), the result is a combined rotation in which the second rotation happens before the first rotation (when applied in the global coordinate frame). Like matrix multiplication, the order in which you multiply quaternions is important.

Tait-Bryan angles

Pitch-yaw-roll angles (also called Tait-Bryan angles) describe three different rotations of the same vector around three different axes, called the pitch, yaw, and roll axes (or the X, Y, Z axes, respectively), which occur one after the other. However:

Related functions:

4x4 Matrices

A 4x4 matrix can describe a 3D vector rotation; see “Rotation”, above.

Planes

A 4-element array can describe a plane in the following manner:

where x, y, and z are the coordinates of any point lying on the plane. * A, B, and C are the X, Y, and Z components of the plane’s normal vector. * D is the signed distance from the plane to the origin (0,0,0). It’s positive if the plane’s normal points toward the origin, and negative if it points away from the origin. * D is the negative dot product of the plane’s normal and any point on the plane.

There is one method that deals with planes:

Boxes

An array of six numbers can describe an axis-aligned bounding box (AABB). If it does, the first three numbers are the box’s minimum X, Y, and Z coordinates, and the last three numbers are the box’s maximum X, Y, and Z coordinates.

If a minimum coordinate is greater than a maximum coordinate, then the box is considered empty.

Methods that deal with boxes include:

Coordinate Systems

There are two conventions of 3D coordinate systems, left-handed and right-handed:

To show this more visually, point one hand’s thumb to your right and its index finger up, and bend the other three fingers halfway down. In a coordinate system named after that hand (left-handed or right-handed), if the positive X axis points in the thumb’s direction and the positive Y axis points in the index finger’s direction, the Z axis will point in the direction the other three fingers point.

As used here, the Z axis is the cross product of two perpendicular axes, namely the X axis and the Y axis, in that order. Which of the X, Y, or Z axes is the right, up, or forward axis is arbitrary; for example, some conventions may have the Z axis, rather than Y, be the up axis. Therefore, these three axes are defined here to avoid confusion.

Differences in Behavior

Projection and view matrices

The difference between a left-handed and right-handed coordinate system affects how 3D points are transformed, mainly in the projection and view matrices. The projection and view matrices returned by Math matrix methods are designed for a right-handed coordinate system. Their documentation describes how to adjust them for a left-handed coordinate system.

Rotation angles (such as used in mat4rotate and quatRotate)

While the axis of rotation points backward from the “eye”, if the angle’s value is positive and the coordinate system is…

While the axis of rotation points backward from the “eye”, if the angle’s value is negative, then the angle runs in the opposite direction.

Cross product (vec3cross) and normals

Given a triangle formed by…

the cross product of the first point with the second, in that order, is a normal of that triangle (a vector that’s perpendicular to the triangle’s surface).

While this particular normal points backward from the “eye”, the triangle’s vertices run in a counterclockwise path for right-handed coordinate systems, or a clockwise path for left-handed systems. (In general, there are two possible choices for normals, which each point in opposite directions.)

Winding and face classification

A two-dimensional triangle has counterclockwise winding if its vertices are ordered in a counterclockwise path from the first to second to third to first vertex. Otherwise, it has clockwise winding. If the triangle is in 3D space, it’s first transformed into 2D window coordinates before its winding is found. (Window coordinates roughly correspond to screen pixels.)

By default, in the WebGL pipeline, triangles with counterclockwise winding are front faces, and other triangles are back faces.

Finding a triangle’s winding

To find a triangle’s winding, do the following calculation (X1, X2, X3 and Y1, Y2, Y3 are the window coordinates of its vertices). Note that half of the result will be the triangle’s signed area.

(X3 - X1) * (Y3 - Y2) - (X3 - X2) * (Y3 - Y1)

If the result is positive, and the window space X axis points right and the positive Y axis points…

If the result is negative, then the triangle has the opposite winding.

Back to documentation index.