Welcome! Log In Create A New Profile

Advanced

Matrix Manipulation Lib

Posted by WiiPhlex 
Matrix Manipulation Lib
August 03, 2008 08:46AM
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[0][0] = cos(radians);      rotateShapeMatrix[0][1] = sin(radians);    rotateShapeMatrix[0][2] = 0.0;
rotateShapeMatrix[1][0] = -sin(radians);     rotateShapeMatrix[1][1] = cos(radians);    rotateShapeMatrix[1][2] = 0.0;
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);
         double c = cos(radians);
         double s = sin(radians);
         
         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);
         double c = cos(radians);
         double s = sin(radians);
    
         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);
         double c = cos(radians);
         double s = sin(radians);
    
         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);
         double c = cos(radians);
         double s = sin(radians);
    
         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.
Re: Matrix Manipulation Lib
August 03, 2008 04:00PM
Thank you very much. Thats awesome.
Sorry, only registered users may post in this forum.

Click here to login