Please send suggestions or corrections for this page to the author at sbuss@ucsd.edu.

This page gives basic documentation for using the GlLinearMath functions. The GlLinearMath routines are a collection of routines for working with vectors in R2, R3, and R4. They were developed for joint use on a number of projects, including the author's ray tracing software and OpenGL code examples.

PAGE UNDER DEVELOPMENT

I. Vector and matrix data types in GlLinearMath

The most commonly used vector and matrix types in GlLinearMath are:

VectorR2
A 2-vector (a point in R2).
VectorR3
A 3-vector (a point in R3).
VectorR4
A 4-vector (a point in R4).
LinearMapR2
A 2x2 matrix.
LinearMapR3
A 3x3 matrix.
LinearMapR4
A 4x4 matrix.

Remark: The matrix classes are built on type of subclasses called Matrix2x2, Matrix3x3 and Matrix4x4. These classes are not really intended to be used directly. Earlier versions of the code also contained classes called RotationMapR2, RotationMapR3, AffineMapR3, RigidMapR2 and RotationMapR4; these have been removed from GlLinearMath, but are still available in VrMath.

II. Including the GlLinearMath code in your project

To work with 2-vectors and 2x2 matrices, you need the files LinearR2.h, LinearR2.cpp, and mathMisc.h. And, you must use #include <LinearR2.h>.

To work with 3-vectors and 3x3 matrices, you need the files LinearR3.h, LinearR3.cpp, and mathMisc.h. And, you must use #include <LinearR3.h>.

To work with 4-vectors and 4x4 matrices, you need the files LinearR3.h, LinearR4.h, LinearR3.cpp, LinearR4.cpp, and mathMisc.h. And, you must use #include <LinearR4.h>.

III. Working with vectors

We discuss mostly VectorR3 below. But the vector classes VectorR2 and VectorR4 work similarly. (The main exception is for crossproduct, which is exclusive to VectorR3.)

Initializing and setting vectors

You can allocate and set a VectorR3 by any of the following methods: this code sets vec1 through vec6 all equal to the vector <1,2,3>.

    VectorR3 vec1(1.0, 2.0, 3.0);
    VectorR3 vec2 = VectorR3(1.0, 2.0, 3.0);
    VectorR3 vec3;
    vec3.Set(1.0, 2.0, 3.0);
    VectorR3 vec4;
    vec4.x = 1.0;
    vec4.y = 2.0;
    vec4.z = 3.0;
    VectorR3 vec5 = vec4;
    double values[3] = {1.0, 2.0, 3.0};
    VectorR3 vec6;
    vec6.Load(&values[0]);

The command vec7.SetZero(); sets a vector equal to zero.

The analogous methods work for VectorR2 and VectorR4's. A VectorR2 has only the members x and y (no z). A VectorR4 has the four members x, y, z and w.

Calculating with vectors

The vector classes support the usual operations of addition (+ and +=) and subtraction (- and -=) of two vectors, multiplication (* and *=) of a vector and a scalar, and division of a vector by a scalar (/ and /=). There is also a special AddScaled command that adds on a scalar multiple of another vector.

As examples, here are four different ways of setting the vector vecA equal to 2*vecB+vecC:

    vecA = 2.0 * vecB + vecC;
    
    vecA = vecB;
    vecA *= 2.0;
    vecA += vecC;
    
    vecA = vecB;
    vecA /= 0.5;
    vecA += vecC;
    
    vecA = vecC;
    vecA.AddScaled(vecB, 2.0);

Vector products

The dot product (^), cross product (*), and the component-wise products can be computed by the following commands. For each command, u, v and w are VectorR3 objects, and dotp is a scalar (a double).

The same commands (except for cross product!) can be used with VectorR2 and VectorR4 objects.

Magnitudes, distances, and normalization

The following functions compute the norm (magnitude) of a vector, or the distances between two vectors. The "Sq" versions return the square of the value: these can be used when possible to avoid a square root. All these functions return a double.

The following method normalize of vector u; namely, it replaces a u with a unit vector in the direction of u. Of course, u should not be the zero vector.

For specialized use only: If u is extremely close to being a unit, a more computationally efficient way to normalize it is to call u.ReNormalize();. This can be useful in animation where roundoff errors can accumulate as vectors are rotated.

III. Working with matrices

We discuss mostly how to use LinearMapR3 objects for linear maps on R3, namely for 3x3 matrices. Only the most commonly useful methods are covered: for a full description of all the methods and functions, see the header file definitions for the classes Matrix3x3 and LinearMapR3. Similar methods work for LinearMapR2's and LinearMapR4's.

Initializing and setting 3x3 matrices

You can explicitly set the entries in either column-order or row-order; however, in keeping with the usual conventions in computer graphics, column-order is preferred. The following lines of code show different ways to load matrices with the entries 1-9, in column order (so that, for instance, the first column contains 1,2,3):

    LinearMapR3 mat1(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0);
    LinearMapR3 mat2;
    mat2.Set(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0);
    
    VectorR3 column1(1.0, 2.0, 3.0), column2(4.0, 5.0, 6.0), column3(7.0, 8.0, 9.0);
    LinearMapR3 mat3(column1, column2, column3);
    LinearMapR3 mat4;
    mat4.Set(column1, column2, column3);

If you want to set a matrix in row order, this can be done with the SetByRows methods; namely,

    LinearMapR3 mat5;
    mat5.SetByRows(1.0, 4.0, 7.0, 2.0, 5.0, 8.0, 3.0, 6.0, 9.0);
    
    VectorR3 row1(1.0, 4.0, 7.0), row2(2.0, 5.0, 8.0), row3(3.0, 6.0, 9.0);
    LinearMapR3 mat6;
    mat6.SetByRows(row1, row2, roy3);

There are convenience commands for setting a matrix to the zero matrix, or the identity matrix:

    mat7.SetZero();         // Set mat7 to the zero matrix
    mat8.SetIdentity();     // Set mat8 to the identity matrix

There are methods SetColumn1, SetColumn2, SetColumn3, SetRow1, SetRow2 and SetRow3 to set a single column or row. There are also that functions to access a single column or row. For instance, mat1.Column1() will return the first column of mat1 as a VectorR3 object.

Calculating with matrices

The matrix classes support the usual operations of addition (+ and +=) and subtraction (- and -=) of two matrices, of multiplication (* and *=) of a matrix and a scalar, and division of a matrix by a scalar (/ and /=) These use the usual C++ syntax; as shown above in the section "Calculating with vectors".

To multiply a matrix and vector, use M * x. For example, with x a VectorR3 and M a LinearMapR3,

    VectorR3 y = M * x;        // Sets y := M*x.    

Transposing and inverting matrices

The following functions allow you to transpose and invert matrices. In the examples, M and N are matrices. MT and M-1 denote the transpose and the inverse of M:

    M = N.Transpose();      // Sets M := NT.
    M.MakeTranspose();      // Sets M := MT.
    M = N.Inverse();        // Sets M := N-1.
    M.Invert();             // Sets M := M-1.

If you do not need to invert a matrix, but just want to solve an equation z = M x, where z is a known vector, you can use:

    VectorR3 x = M.Solve(z);    // Sets x := M-1(z)

There are also some specialized functions for multiplying by matrices on the right, and for multiplying by a transposed matrix.

    M *= N;                          // Sets M := M * N.
    M.LeftMultiplyBy(N);             // Sets M := N * M.
    M.RightMultiplyByTranspose(N);   // Sets M := M * (NT).
    M.LeftMultiplyByTranspose(N);    // Sets M := (NT) * M.

IV. Reproducing the OpenGL operations on matrices (LinearMapR4's).

The LinearMapR4 contains functions for reproducing the functionality of legacy OpenGL commands for projection and modelview matrices. These include the following commands for setting a matrix M (that is, a LinearMapR4 M). For more details on these see the author's textbook on 3D Computer Graphics (second edition) or other OpenGL documentation. The rotation functions in LinearMapR4 take angles in radians (unlike OpenGL, not degrees!)

    M.Set_glScale(alpha);            // Same as M.Set_glScale( alpha, alpha, alpha) -- Uniform scaling.
    M.Set_glScale(x, y ,z);          // Set M to nonuniform scaling matrix.
    M.Set_glTranslate(x, y, z);      // Set M to matrix for translation by <x,y,z>.
    M.Set_glTranslate(vec);          // Set M to matrix for translation by VectorR3 vec.
    M.Set_glRotate(angle, x, y, z);  // Set M to matrix that rotates angle radians around <x,y,z>.
    M.Set_glRotate(angle, vec);      // Set M to matrix that rotates angle radians around VectorR3 vec.
    
    M.Set_glFrustum(left, right, bottom, top, near, far);          // Set M to OpenGL glFrustum matrix.
    M.Set_glOrtho(left, right, bottom, top, near, far);            // Set M to OpenGL glOrtho matrix.
    M.Set_gluPerspective(fov_y_radians, aspectRatio, zNear, zFar); // Set M to OpenGL gluPerspective matrix.
    M.Set_gluLookAt(eyePos, lookAtPos, upDir);                     // Set M to OpenGL gluLookAt matrix
                                                                   //  - eyePos, lookAtPos, upDir are VectorR3's

The first block of functions have corresponding functions which multiply M on the right by the indicated matrix (similar to legacy OpenGL functions):

    M.Mult_glScale(alpha);            // Same as M.Mult_glScale( alpha, alpha, alpha) -- Uniformly scale.
    M.Mult_glScale(x, y ,z);          // Multiply M by nonuniform scaling matrix.
    M.Mult_glTranslate(x, y, z);      // Multiply M by matrix for translation by <x,y,z>.
    M.Mult_glTranslate(vec);          // Multiply M by matrix for translation by VectorR3 vec.
    M.Mult_glRotate(angle, x, y, z);  // Multiply M by matrix that rotates angle radians around <x,y,z>.
    M.Mult_glRotate(angle, vec);      // Multiply M by matrix that rotates angle radians around VectorR3 vec.

V. Cross products and projections with LinearMapR3's

There are also some useful functions for manipulating linear transformations in R3. These include the following, where u and w are VectorR3's; and M is a LinearMapR3.

    M.SetCrossProductMatrix( const VectorR3& u );    // Set M equal to the crossproduct matrix M.
                                                     // Then M*w will equal u*w (vector crossproduct).

    M = LinearMapR3 VectorProjectMap( u );      // Set M equal to the linear map that projects onto the vector u.
                                                // Important: u must be a unit vector.
                                                           
    M = LinearMapR3 PlaneProjectMap ( w );      // Set M equal to the linear map that projects onto the plane P
                                                //       that is perpendicular to w and contains the origin.
                                                // Important: w must be a unit vector.

There are other special VectorR3 and LinearMapR3 functions available; for these, see the header file declarations.

VI. Dump functions

The "Dump" functions work oppositely to the "Load" functions mentioned above. They allow writing the entries of a vector or a matrix into an array of floats or doubles. We illustrate the dump function for a LinearMapR4 object M:

    float valuesf[16];              // Allocate space for all 16 entries
    M.DumpByColumns(&valuesf[0]);   // Store entries in column order in the array.

The function DumpByColumns with float's is helpful to extract a matrix's entries for use with OpenGL.