Matrix lib

The following is a set of C++ routines for working with 4x4 matrices. These routines offer rotation, scaling, and translation. You may use them freely in your code. If you have any comments on them, please email us.

#include <cstdlib>
#include <iostream>
#include <math.h>

using namespace std;

struct Matrix
{
float e[16];              

inline float& operator[](int index) {return e[index];}
inline const float& operator[](int index) const {return e[index];}
};

struct Vector
{
float e[4];              

inline float& operator[](int index) {return e[index];}
inline const float& operator[](int index) const {return e[index];}
};

ostream& operator<<(ostream& out, Matrix &m);
ostream& operator<<(ostream& out, Vector &v);

Matrix buildidentitymatrix(void);
Matrix buildrotationmatrix(float theta, float x, float y, float z);
Matrix buildscalematrix(float x, float y, float z);
Matrix buildtranslationmatrix(float x, float y, float z);

Vector buildvector(float x, float y, float z);

Matrix operator*(const Matrix &a, const Matrix &b);
void operator*=(Matrix &a, const Matrix &b);
Vector operator*(const Matrix &a, const Vector &v);

ostream& operator<<(ostream& out, const Matrix &m)
{
out << m[0] << " " << m[4] << " " <<  m[8] << " " <<  m[12] << endl;
out << m[1] << " " <<  m[5] << " " <<  m[9] << " " <<  m[13] << endl;
out << m[2] << " " <<  m[6] << " " <<  m[10] << " " <<  m[14] << endl;
out << m[3] << " " <<  m[7] << " " <<  m[11] << " " <<  m[15];
return out;         
}

ostream& operator<<(ostream& out, Vector &v)
{
out << "(" << v[0] << ", " << v[1] << ", " <<  v[2] << ")";
return out;         
}

Matrix buildidentitymatrix(void)
{
Matrix m;       
m[0] = 1;
m[1] = 0;
m[2] = 0;
m[3] = 0;

m[4] = 0;
m[5] = 1;
m[6] = 0;
m[7] = 0;

m[8] = 0;
m[9] = 0;
m[10] = 1;
m[11] = 0;

m[12] = 0;
m[13] = 0;
m[14] = 0;
m[15] = 1;     

return m;
}

Matrix buildrotationmatrix(float theta, float x, float y, float z)
{
Matrix m;       
float c = cos(theta);
float s = sin(theta);
float t = 1 - cos(theta);     
m[0] = t*x*x + c;
m[1] = t*x*y + s*z;
m[2] = t*x*z - s*y;
m[3] = 0;
     
m[4] = t*x*y - s*z;
m[5] = t*y*y + c;
m[6] = t*y*z + s*x;
m[7] = 0;

m[8] = t*x*z + s*y;
m[9] = t*y*z - s*x;
m[10] = t*z*z + c;
m[11] = 0;

m[12] = 0;
m[13] = 0;
m[14] = 0;
m[15] = 1;          

return m;
}

Matrix buildscalematrix(float x, float y, float z)
{
Matrix m;     
     
m[0] = x;
m[1] = 0;
m[2] = 0;
m[3] = 0;

m[4] = 0;
m[5] = y;
m[6] = 0;
m[7] = 0;

m[8] = 0;
m[9] = 0;
m[10] = z;
m[11] = 0;

m[12] = 0;
m[13] = 0;
m[14] = 0;
m[15] = 1;     

return m;
}

Matrix buildtranslationmatrix(float x, float y, float z)
{
Matrix m;
m[0] = 1;
m[1] = 0;
m[2] = 0;
m[3] = 0;

m[4] = 0;
m[5] = 1;
m[6] = 0;
m[7] = 0;

m[8] = 0;
m[9] = 0;
m[10] = 1;
m[11] = 0;

m[12] = x;
m[13] = y;
m[14] = z;
m[15] = 1;     
return m;
}

Matrix operator*(const Matrix &a, const Matrix &b)
{    
Matrix m;     

m[0] = b[0]*a[0] + b[1]*a[4] + b[2]*a[8] + b[3]*a[12];
m[1] = b[0]*a[1] + b[1]*a[5] + b[2]*a[9] + b[3]*a[13];
m[2] = b[0]*a[2] + b[1]*a[6] + b[2]*a[10] + b[3]*a[14];
m[3] = b[0]*a[3] + b[1]*a[7] + b[2]*a[11] + b[3]*a[15];

m[4] = b[4]*a[0] + b[5]*a[4] + b[6]*a[8] + b[7]*a[12];
m[5] = b[4]*a[1] + b[5]*a[5] + b[6]*a[9] + b[7]*a[13];
m[6] = b[4]*a[2] + b[5]*a[6] + b[6]*a[10] + b[7]*a[14];
m[7] = b[4]*a[3] + b[5]*a[7] + b[6]*a[11] + b[7]*a[15];

m[8] = b[8]*a[0] + b[9]*a[4] + b[10]*a[8] + b[11]*a[12];
m[9] = b[8]*a[1] + b[9]*a[5] + b[10]*a[9] + b[11]*a[13];
m[10] = b[8]*a[2] + b[9]*a[6] + b[10]*a[10] + b[11]*a[14];
m[11] = b[8]*a[3] + b[9]*a[7] + b[10]*a[11] + b[11]*a[15];

m[12] = b[12]*a[0] + b[13]*a[4] + b[14]*a[8] + b[15]*a[12];
m[13] = b[12]*a[1] + b[13]*a[5] + b[14]*a[9] + b[15]*a[13];
m[14] = b[12]*a[2] + b[13]*a[6] + b[14]*a[10] + b[15]*a[14];
m[15] = b[12]*a[3] + b[13]*a[7] + b[14]*a[11] + b[15]*a[15];     

return m;
}


void operator*=(Matrix &a, const Matrix &b)
{
a = a*b;
}

Vector buildvector(float x, float y, float z)
{
Vector v;
v[0] = x;
v[1] = y;
v[2] = z;
v[3] = 1;
return v;              
}

Vector operator*(const Matrix &a, const Vector &v)
{
Vector vnew;

vnew[0] = v[0]*a[0] + v[1]*a[4] + v[2]*a[8] + v[3]*a[12];
vnew[1] = v[0]*a[1] + v[1]*a[5] + v[2]*a[9] + v[3]*a[13];
vnew[2] = v[0]*a[2] + v[1]*a[6] + v[2]*a[10] + v[3]*a[14];
vnew[3] = v[0]*a[3] + v[1]*a[7] + v[2]*a[11] + v[3]*a[15];

return vnew;
}