# Matrix Manipulation Lib

Posted by WiiPhlex
 WiiPhlex Matrix Manipulation Lib August 03, 2008 08:46AM Registered: 16 years agoPosts: 211
I'm working on a game and thought I may as well release the Matrix Manipulation library I've done for it in open source. Its use is for people who do graphics the old school way for whatever reason (I did it for fun). Simple enough source code, just watch out for the namespace's it can get a little complicated due to the way I've included functions under the same name for both 2D and 3D graphics transformations. Most people wonder why I would do all of the mathematics from scratch in a 3D application no less when theres libraries all over the place for this stuff!!! Because I'm not lazy...
Anyway, I may update it further along for optimization, for 3D it uses Perspective projection over Parallel projection, therefore I've programmed a custom z buffer if you wish to edit any part and/or use it feel free too, its just some mathematic functions.
Source is provided here.

MatrixUtility.h
```#ifndef __MATRIXUTILITY_H__
#define __MATRIXUTILITY_H__

/////////////////////////////////
// Matrix Manipulation library //
/////////////////////////////////

// By WiiPhlex
// MatrixUtility.h

// 2DData
namespace 2D
{
// vertex structure
typedef struct vertex
{
int x, y; // x and y Cartesian coordinates of a vertex
} VERTEX;

// shape structure
typedef struct shape
{
int numVerts; // number of verticies in the shape.
VERTEX* verticies; // pointer to an array of vertex stuctures.
} SHAPE;

typedef struct vector
{
int x, y, w; // w usually == 1
} VECTOR;

typedef double MATRIX3X3[3][3];  // matrix struct
}

namespace 3D
{
// 3Dimensional
// vertex structre
typedef struct vertex
{
int x, y, z, w;
} VERTEX;

// edge structure
typedef struct edge
{
unsigned int vertex1, vertex2;
} EDGE;

// Model structure
typedef struct model
{
unsigned int numVerts;
VERTEX* verticies;
unsigned int numEdges;
EDGE* edges;
} MODEL;

typedef double MATRIX4X4[4][4]; // matrix struct

}

#endif // __MATRIXUTILITY_H__```

MatrixUtility.cpp
```//////////////////////////////////////
// 2D Graphics Manipulation library //
//////////////////////////////////////

// By WiiPhlex
// MatrixUtility.cpp

#include "MatrixUtility.h"

/* These Matricies are reference for the Transformations.

IdentityMatrix
MATRIX3X3 IdentityMatrix;
IdentityMatrix[0][0] = 1.0;            IdentityMatrix[0][1] = 0.0;          IdentityMatrix[0][2] = 0.0;
IdentityMatrix[1][0] = 0.0;            IdentityMatrix[1][1] = 1.0;          IdentityMatrix[1][2] = 0.0;
IdentityMatrix[2][0] = 0.0;            IdentityMatrix[2][1] = 0.0;          IdentityMatrix[2][2] = 1.0;

// TRANSLATE MATRIX
MATRIX3X3 translateShapeMatrix;
translateShapeMatrix[0][0] = 1.0;            translateShapeMatrix[0][1] = 0.0;          translateShapeMatrix[0][2] = 0.0;
translateShapeMatrix[1][0] = 0.0;            translateShapeMatrix[1][1] = 1.0;          translateShapeMatrix[1][2] = 0.0;
translateShapeMatrix[2][0] = xTrans;         translateShapeMatrix[2][1] = yTrans;       translateShapeMatrix[2][2] = 1.0;

// SCALE MATRIX
MATRIX3X3 scaleShapeMatrix;
scaleShapeMatrix[0][0] = xScaleFactor;       scaleShapeMatrix[0][1] = 0.0;              scaleShapeMatrix[0][2] = 0.0;
scaleShapeMatrix[1][0] = 0.0;                scaleShapeMatrix[1][1] = yScaleFactor;     scaleShapeMatrix[1][2] = 0.0;
scaleShapeMatrix[2][0] = 0.0;                scaleShapeMatrix[2][1] = 0.0;              scaleShapeMatrix[2][2] = 1.0;

// ROTATION MATRIX
MATRIX3X3 rotateShapeMatrix;
rotateShapeMatrix[2][0] = 0.0;               rotateShapeMatrix[2][1] = 0.0;             rotateShapeMatrix[2][2] = 1.0; */

// ******************** 2DTransform namespace *******************
namespace 2DTransform
{

using namespace 2D;

/* MultiMatrix

Parameters: A reference to a 3X3 Matrix, reference to the two matricies being multiplied.

*/

void MultiMatrix(MATRIX3X3& product,
MATRIX3X3& matrix1,
MATRIX3X3& matrix2)

{
for (int x = 0; x < 3; ++x)
for (int y = 0; y < 3; ++y)
{
double sum = 0;
for (int z = 0; z < 3; ++z)
sum += matrix[x][z] * matrix2[z][y];
product[x][y] = sum;
}
}

/* Example of use

MATRIX3X3 m1, m2 m3;

m1[0][0] = 1.0;            m1[0][1] = 0.0;          m1[0][2] = 0.0;
m1[1][0] = 0.0;            m1[1][1] = 1.0;          m1[1][2] = 0.0;
m1[2][0] = 0.0;            m1[2][1] = 0.0;          m1[2][2] = 1.0;

m2[0][0] = 9.0;            m2[0][1] = 8.0;          m2[0][2] = 7.0;
m2[1][0] = 6.0;            m2[1][1] = 5.0;          m2[1][2] = 4.0;
m2[2][0] = 3.0;            m2[2][1] = 2.0;          m2[2][2] = 1.0;

MultiMatrix(m3, m1 ,m2); */

/* Transform

Parameters: a reference to a SHAPE structure and reference to a MATRIX3X3 array

*/
void Transform(SHAPE& shape, MATRIX3X3& m)
{
int transformedX, transformedY;

for (int x = 0; x < shape.numVerts; ++x)
{
transformedX = (int) (shape.verticies[x].x * m[0][0] + shape.verticies[x].y * m[1][0] + m[2][0]);
transformedY = (int) (shape.verticies[x].x * m[0][1] + shape.verticies[x].y * m[1][1] + m[2][1]);

shape.verticies[x].x = transformedX;
shape.verticies[x].y = transformedY;
}
}

/* InitMatrix

Parameters: reference to a MATRIX3X3 array

*/
void InitMatrix(MATRIX3X3& m)
{
m1[0][0] = 1.0;            m1[0][1] = 0.0;          m1[0][2] = 0.0;
m1[1][0] = 0.0;            m1[1][1] = 1.0;          m1[1][2] = 0.0;
m1[2][0] = 0.0;            m1[2][1] = 0.0;          m1[2][2] = 1.0;
}

/* CopyMatrix

Parameters: reference to the destination and source matricies both of which
are the type MATRIX3X3

*/
void CopyMatrix(MATRIX3X3& dst, MATRIX3X3& src)
{
for (int i = 0; i < 3; ++i)
for (int j = 0; j < 3; ++j)
dst[j] = src[j];
}

//                    TRANSFORMATION FUNCTIONS
/* Translate

Parameters: reference to the matrix that holds the current state of transformation
and the x and y values of the translation.

*/

void Translate(MATRIX3X3& m, int xTrans, int yTrans)
{
MATRIX3X3 translateShapeMatrix, m2;

translateShapeMatrix[0][0] = 1.0;            translateShapeMatrix[0][1] = 0.0;          translateShapeMatrix[0][2] = 0.0;
translateShapeMatrix[1][0] = 0.0;            translateShapeMatrix[1][1] = 1.0;          translateShapeMatrix[1][2] = 0.0;
translateShapeMatrix[2][0] = xTrans;         translateShapeMatrix[2][1] = yTrans;       translateShapeMatrix[2][2] = 1.0;

MultiMatrix(m2, translateShapeMatrix, m);
CopyMatrix (m, m2);
}

/* Scale

Parameters: reference to the current transformation matrix and the x and y scaling factors

*/
void Scale(MATRIX3X3& m, double xScaleFactor, double yScaleFactor)
{
MATRIX3X3 translateShapeMatrix, m2;

translateShapeMatrix[0][0] = xScaleFactor;   translateShapeMatrix[0][1] = 0.0;          translateShapeMatrix[0][2] = 0.0;
translateShapeMatrix[1][0] = 0.0;            translateShapeMatrix[1][1] = yScaleFactor; translateShapeMatrix[1][2] = 0.0;
translateShapeMatrix[2][0] = 0.0;            translateShapeMatrix[2][1] = 0.0;          translateShapeMatrix[2][2] = 1.0;

MultiMatrix(m2, translateShapeMatrix, m);
CopyMatrix (m, m2);
}

/* Rotate

Parameters: reference to the current transformation matrix and the number of degrees to rotate

*/
void Rotate(MATRIX3X3& m, int degrees)
{
MATRIX3X3 rotateShapeMatrix, m2;

if (degrees == 0) return; // return to main if there is no degree of rotation

// convert from degrees to radians as this is how computers work best.
double radians = 6.283185308 / (360.0 / degrees);

rotateShapeMatrix[0][0] =  c;      rotateShapeMatrix[0][1] = s;    rotateShapeMatrix[0][2] = 0.0;
rotateShapeMatrix[1][0] = -s;      rotateShapeMatrix[1][1] = c;    rotateShapeMatrix[1][2] = 0.0;
rotateShapeMatrix[2][0] = 0.0;     rotateShapeMatrix[2][1] = 0.0;  rotateShapeMatrix[2][2] = 1.0;

MultiMatrix(m2, rotateShapeMatrix, m);
CopyMatrix (m, m2);
}
} // ************ END 2DTransform NAMESPACE **************//

// **************** 3DTransformations namespace **************
namespace 3DTransformations
{

using namespace 3D;

// 3D Functions for Matrix manipulation
/* PerspProject

Parameters: reference to a model structure and the eye value required to calculate the viewpoint.

Perspective Projection Forumla: double t = 1.0 / (1.0 zCoord / eye);
perspX = (int) (xCoord * t);
perspY = (int) (yCoord * t);

*/
void PerspProject(MODEL& model, double eye)
{
for (unsigned int i = 0; i < model.numVerts; ++i)
{

int xCoord = model.verticies.x;
int yCoord = model.verticies.y;
int zCoord = model.verticies.z;

double t = 1.0 / (1.0 zCoord / eye);

model.verticies.x = (int) (xCoord * t);
model.verticies.y = (int) (yCoord * t);
}
}

/* InitMatrix

Parameters: reference to the current transformation matrix

*/
InitMatrix MATRIX4X4& m)
{
m[0][0] = 1.0;   m[0][1] = 0.0;   m[0][2] = 0.0;     m[0][3] = 0.0;
m[1][0] = 0.0;   m[1][1] = 1.0;   m[1][2] = 0.0;     m[1][3] = 0.0;
m[2][0] = 0.0;   m[2][1] = 0.0;   m[2][2] = 1.0;     m[2][3] = 0.0;
m[3][0] = 0.0;   m[3][1] = 0.0;   m[3][2] = 0.0;     m[3][3] = 1.0;
}

/* CopyMatrix

Parameters: reference to the destination and source matricies both of which
are the type MATRIX4X4

*/
void CopyMatrix(MATRIX4X4& dst, MATRIX4X4& src)
{
for (int i = 0; i < 4; ++i)
for (int j = 0; j < 4; ++ j)
dst[j] = src[j];
}

/* MultiMatrix

Parameters: A reference to a 4X4 Matrix, reference to the two matricies being multiplied.

*/

void MultiMatrix(MATRIX4X4& product,
MATRIX4X4& matrix1,
MATRIX4X4& matrix2)

{
for (int x = 0; x < 4; ++x)
for (int y = 0; y < 4; ++y)
{
double sum = 0;
for (int z = 0; z < 4; ++z)
sum += matrix[x][z] * matrix2[z][y];
product[x][y] = sum;
}
}

/* Translate

Parameters: reference to the matrix that holds the current state of transformation
and the x, y and z values of the translation.

*/

void Translate(MATRIX4X4& m, int xTrans, int yTrans, int zTrans)
{
MATRIX4X4 m1, m2;

m1[0][0] = 1.0;      m1[0][1] = 0.0;      m1[0][2] = 0.0;        m1[0][3] = 0.0;
m1[1][0] = 0.0;      m1[1][1] = 1.0;      m1[1][2] = 0.0;        m1[1][3] = 0.0;
m1[2][0] = 0.0;      m1[2][1] = 0.0;      m1[2][2] = 1.0;        m1[2][3] = 0.0;
m1[3][0] = xTrans;   m1[3][1] = yTrans;   m1[3][2] = zTrans;     m1[3][3] = 1.0;

MultiMatrix(m2, m1, m);
CopyMatrix (m, m2);
}

/* Scale

Parameters: reference to the current transformation matrix and the x, y and z scaling factors

*/
void Scale(MATRIX4X4& m, double xScaleFactor, double yScaleFactor, double zScaleFactor)
{
MATRIX4X4 m1, m2;

m1[0][0] = xScaleFactor;      m1[0][1] = 0.0;               m1[0][2] = 0.0;                 m1[0][3] = 0.0;
m1[1][0] = 0.0;               m1[1][1] = yScaleFactor;      m1[1][2] = 0.0;                 m1[1][3] = 0.0;
m1[2][0] = 0.0;               m1[2][1] = 0.0;               m1[2][2] = zScaleFactor;        m1[2][3] = 0.0;
m1[3][0] = 0.0;               m1[3][1] = 0.0;               m1[3][2] = 0.0;                 m1[3][3] = 1.0;

MultiMatrix(m2, m1, m);
CopyMatrix (m, m2);
}

/* RotateZ

Parameters: reference to the current transformation matrix and the angle of rotation for the z axis

*/
void RotateZ(MATRIX4X4& m, int zAngle)
{
MATRIX4X4 m1, m2;

if (zAngle == 0) return; // return to main if there is no degree of rotation

// convert from degrees to radians as this is how computers work best.
double radians = 6.283185308 / (360.0 / degrees);

m1[0][0] =  c;      m1[0][1] = s;    m1[0][2] = 0.0;     m1[0][3] = 0.0;
m1[1][0] = -s;      m1[1][1] = c;    m1[1][2] = 0.0;     m1[1][3] = 0.0;
m1[2][0] = 0.0;     m1[2][1] = 0.0;  m1[2][2] = 1.0;     m1[2][3] = 0.0;
m1[3][0] = 0.0;     m1[3][1] = 0.0;  m1[3][2] = 0.0;     m1[3][3] = 1.0;

MultiMatrix(m2, m1, m);
CopyMatrix (m, m2);

}

/* RotateX

Parameters: reference to the current transformation matrix and the angle of rotation for the x axis

*/
void RotateZ(MATRIX4X4& m, int xAngle)
{
MATRIX4X4 m1, m2;

if (xAngle == 0) return; // return to main if there is no degree of rotation

// convert from degrees to radians as this is how computers work best.
double radians = 6.283185308 / (360.0 / degrees);

m1[0][0] = 1.0;     m1[0][1] = 0.0;  m1[0][2] = 0.0;     m1[0][3] = 0.0;
m1[1][0] = 0.0;     m1[1][1] = c;    m1[1][2] =   s;     m1[1][3] = 0.0;
m1[2][0] = 0.0;     m1[2][1] = -s;   m1[2][2] =   c;     m1[2][3] = 0.0;
m1[3][0] = 0.0;     m1[3][1] = 0.0;  m1[3][2] = 0.0;     m1[3][3] = 1.0;

MultiMatrix(m2, m1, m);
CopyMatrix (m, m2);

}

/* RotateY

Parameters: reference to the current transformation matrix and the angle of rotation for the y axis

*/
void RotateZ(MATRIX4X4& m, int yAngle)
{
MATRIX4X4 m1, m2;

if (yAngle == 0) return; // return to main if there is no degree of rotation

// convert from degrees to radians as this is how computers work best.
double radians = 6.283185308 / (360.0 / degrees);

m1[0][0] = c  ;     m1[0][1] = 0.0;  m1[0][2] = -s ;     m1[0][3] = 0.0;
m1[1][0] = 0.0;     m1[1][1] = 1.0;  m1[1][2] = 0.0;     m1[1][3] = 0.0;
m1[2][0] = s  ;     m1[2][1] = 0.0;  m1[2][2] =  c;      m1[2][3] = 0.0;
m1[3][0] = 0.0;     m1[3][1] = 0.0;  m1[3][2] = 0.0;     m1[3][3] = 1.0;

MultiMatrix(m2, m1, m);
CopyMatrix (m, m2);

}
}
```

If you find any errors please tell me.
 Arikado Re: Matrix Manipulation Lib August 03, 2008 04:00PM AdminRegistered: 16 years agoPosts: 5,132
Thank you very much. Thats awesome.
Sorry, only registered users may post in this forum.