#### Archived

This topic is now archived and is closed to further replies.

# code review, matrix manipulation and projections

This topic is 5227 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

/****************************************************
TITLE:     Simple GFX API
FILE:      trans.h
AUTHOR:    Sean T. McBeth, sm8236@ship.edu
DATES:     part 1: 2/10/04 - 2/25/04
part 2: 3/20/04 - 3/26/04
PROFESSOR: Dr. David J. Mooney, djmoon@ship.edu
COURSE:    CSC 460: Computer Graphics Algorithms
*****************************************************/
#ifndef __TRANS_H
#define __TRANS_H
#ifndef __MATH_H
#include <math.h>
#endif
#ifndef __glut_h__
#include <gl/glut.h>
#endif

#ifdef __DEBUG__
#include <stdio.h>
#endif
#define real float

////////////////////////

//necessary structures//

////////////////////////

struct point{
real x, y, z;
};

struct matrix{
//a 3D point, used for some stuff

//a 4X4 matrix, used for some other stuff

real a[4][4];
};

struct node{
//Create a STACK!!!!!!!!!!!!!!!!!!!!!!

matrix m;
node*  n;
};

enum{PARALLEL, PERSPECTIVE};

///////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////

////////////////////////////////

//matrix operations prototypes//

////////////////////////////////

void   setProjection         (const int,
const real,    const real,    const real,
const real,    const real,    const real,
const real,    const real,    const real);
void   setVRC                (const real,    const real,    const real,
const real,    const real,    const real,
const real,    const real,    const real);
int    clipLine              (const point&,  const point&,
const real,    const real,    const real,    const real);
int    clipPoint             (const point&,  const real,    const real,    const real,    const real);
void   setView               (const int,     const int,     const int,     const int);
void   rotate                (const real,    const real,    const real,    const real);
void   translate             (const real,    const real,    const real);
void   scale                 (const real,    const real,    const real);
void   multMatrix            (      matrix&, const matrix&);
void   copyMatrix            (const matrix&,       matrix&);
void   drawLine              (const point&,  const point&);
void   shearxy               (const real,    const real);
void   shearxz               (const real,    const real);
void   shearyx               (const real,    const real);
void   identMatrix           (      matrix&);
point  transformPoint        (const point&);
void   drawPoint             (const point&);
void   rotatex               (const real);
void   rotatey               (const real);
void   rotatez               (const real);
void   initializeTransMatrix (void);
void   pushMatrix            (void);
void   popMatrix             (void);

///////////////////////////////////////////////////////////////////////

//some special debugging functions

#ifdef __DEBUG__
void printMatrix(const matrix& m){
for(int y=0;y<4;++y){
printf("|");
for(int x=0;x<4;++x){
printf("%f ",m.a[y][x]);
}
printf("|\n");
}
printf("\n");
}
void printPoint(const point& p){
printf("x%f y%f z%f\n", p.x, p.y, p.z);
}
#endif
//get rid of the debugging functions if not in debug mode

#ifndef __DEBUG__
#define printMatrix(x)
//void printMatrix(const matrix& m){   return;}

#define printPoint(x)
//void printPoint(const point& p){   return;}

#endif
///////////////////////////////////////////////////////////////////////

///////////

//globals//

///////////

matrix        transMatrix;       //the current transformation matrix

matrix        viewMatrix;        //specifies the mapping of the world window to the viewport

matrix        projMatrix;        //the current projection matrix

node*         transMatrixStack;  //the matrix stack;

///////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////

////////////////////////////////

//matrix operations defintions//

////////////////////////////////

/*
FUNC: setProjection
PRE:  type, prp<x,y,z>, left, right, bottom, top, front, and back are all set
0<=type<=1
left<right && bottom<top && front<back
setVRC has been previously called
POST: the world window-to-viewport transformation will be finished
the current projection matrix will be set

*/
void   setProjection         (const int type,
const real prpx,   const real prpy,    const real prpz,
const real left,   const real right,   const real bottom,
const real top,    const real front,   const real back){
real shx, shy, dh, dv, dd, t1, t2;
dh = right - left;
dv = top - bottom;
dd = front - back;
pushMatrix();
if(viewMatrix.a[3][3]==1)
copyMatrix(viewMatrix, transMatrix);
else
initializeTransMatrix();
scale( 1/(right - left), 1/(top - bottom), 1);
translate( -left, -bottom, 0);
copyMatrix(transMatrix, viewMatrix);

/*
needed for the world window-to-viewport transformation. This inof
will be provided by setView.
*/

copyMatrix(projMatrix, transMatrix);

if(type == PERSPECTIVE){
//T(-COP)

translate(-prpx, -prpy, -prpz);
}

//H(DOP || to z axis)

shx = ( dh / 2) - prpx;
shy = ( dv / 2) - prpy;
shearxy(shx, shy);

if(type == PARALLEL){
//T(-CW)

translate( -dh / 2, -dv / 2, -front);
//scale to canonical parallel view volume

scale( 2 / dh, 2 / dv, 1 / dd );
}
else{
//scale to canonical perspective view volume

t1 = 2 * -prpz;
t2 = -prpz + back;
scale( t1 / ( dh * t2 ), t1 / ( dv * t2 ), -1 / t2 );
}
/*
projection matrix is set!
*/
popMatrix();
}

/*
FUNC: setVRC
PRE:  vrp<x,y,z> is set. vpn<x,y,z> and vup<x,y,z> are non-parallel vectors
POST: view reference coordinate system will be initialized
call setProjection next
*/
void   setVRC                (const real vrpx,    const real vrpy,    const real vrpz,
const real vpnx,    const real vpny,    const real vpnz,
const real vupx,    const real vupy,    const real vupz){
matrix temp;
real vpnLen;
real tx, ty, tz, tlen;
pushMatrix();
initializeTransMatrix();

//T(-VRP)

translate(-vrpx, -vrpy, -vrpz);
identMatrix(temp);

//Rz = VPN / ||VPN||

vpnLen = sqrt( vpnx*vpnx + vpny*vpny + vpnz*vpnz );
temp.a[2][0] = vpnx/vpnLen;
temp.a[2][1] = vpny/vpnLen;
temp.a[2][2] = vpnz/vpnLen;

//Rx = (VUP X Rz) / ||(VUP X Rz)||

tx = vupy*temp.a[2][2] - vupz*temp.a[2][1];
ty = vupz*temp.a[2][0] - vupx*temp.a[2][2];
tz = vupx*temp.a[2][1] - vupy*temp.a[2][0];
tlen = sqrt( tx*tx + ty*ty + tz*tz );
temp.a[0][0] = tx/tlen;
temp.a[0][1] = ty/tlen;
temp.a[0][2] = tz/tlen;

//Ry = Rz X Rx

tx = temp.a[2][1]*temp.a[0][2] - temp.a[2][2]*temp.a[0][1];
ty = temp.a[2][2]*temp.a[0][0] - temp.a[2][0]*temp.a[0][2];
tz = temp.a[2][0]*temp.a[0][1] - temp.a[2][1]*temp.a[0][0];
tlen = sqrt( tx*tx + ty*ty + tz*tz );
temp.a[1][0] = tx/tlen;
temp.a[1][1] = ty/tlen;
temp.a[1][2] = tz/tlen;

//Rotate VRC inline with cartesian coordinate system

multMatrix(transMatrix, temp);
copyMatrix(projMatrix, transMatrix);
/*
At this point, the projection matrix is only half complete.
*/
popMatrix();
}
int    clipLine              (const point&,  const point&,
const real,    const real,    const real,    const real);
int    clipPoint             (const point&,  const real,    const real,    const real,    const real);
/*
FUNC: setView
PRE:  xmin, xmax, ymin, ymax are valid integers
xmin<xmax && ymin<ymax
POST: the preliminary informartion for creating a world window-to-viewport
transformation will be stored in the viewMatrix.

*/
void   setView               (const int xmin,     const int xmax,     const int ymin,     const int ymax){
pushMatrix();
if(viewMatrix.a[3][3]==1)
copyMatrix(viewMatrix, transMatrix);
else
initializeTransMatrix();
translate(xmin, xmax, 0);
scale( (xmax - xmin), (ymax - ymin), 1);
copyMatrix(transMatrix, viewMatrix);
popMatrix();
/*
needed for the world window-to-viewport transformation. This info
will be provided by setProjection.
*/
}

/*
FUNC: rotate
PRE:  [x y z] NOT zero vector
POST: scene will be rotated by theta degrees about an arbitrary axis
*/
void   rotate                (const real theta,    const real ax,    const real ay,    const real az){
real c=cos(theta);
real s=sin(theta);
matrix rot;
identMatrix(rot);
rot.a[0][0]=ax*ax*(1-c)+c;
rot.a[0][1]=ax*ay*(1-c)+az*s;
rot.a[0][2]=ax*az*(1-c)-ay*s;

rot.a[1][0]=ay*ax*(1-c)-az*s;
rot.a[1][1]=ay*ay*(1-c)+c;
rot.a[1][2]=ay*az*(1-c)+ax*s;

rot.a[2][0]=az*ax*(1-c)+ay*s;
rot.a[2][1]=az*ay*(1-c)-ax*s;
rot.a[2][2]=az*az*(1-c)+c;

multMatrix(transMatrix, rot);
}
/*
FUNC: translate
PRE:  dx AND dy AND dz NOT NULL
POST: current transformation matrix translated by dx, dy, dz
*/
void  translate             (const real dx,    const real dy,    const real dz){
matrix temp;
identMatrix(temp);
temp.a[0][3] = dx;
temp.a[1][3] = dy;
temp.a[2][3] = dz;
multMatrix(transMatrix, temp);
}

/*
FUNC: scale
PRE:  sx AND sy AND sz NOT NULL
POST: current transformation matrix scaled by sx, sy, sz
*/
void  scale                 (const real sx,    const real sy,    const real sz){
matrix temp;
identMatrix(temp);
temp.a[0][0] = sx;
temp.a[1][1] = sy;
temp.a[2][2] = sz;
multMatrix(transMatrix, temp);
}

/*
FUNC: multMatrix
PRE:  m1 AND m2 NOT NULL
m1 AND m2 valid 4X4 matrix
POST: m1=m1*m2, via normal matrix multiplication
*/
void  multMatrix            (matrix& m1, const matrix& m2){
matrix temp;
for(int y = 0; y < 4; ++y){
for(int x = 0; x < 4; ++x){
//initialize temp

temp.a[y][x] = 0;
//do multiplication

for(int i = 0; i < 4; ++i){
temp.a[y][x] += m1.a[y][i] * m2.a[i][x];
}
}
}
copyMatrix(temp, m1);
}

/*
FUNC: copyMatrix
PRE:  src is a valid matrix
POST: dest will be a value-for-value copy of src
*/
void   copyMatrix            (const matrix& src,       matrix& dest){
for(int y=0; y<4; ++y){
for(int x=0; x<4; ++x){
dest.a[y][x]=src.a[y][x];
}
}
}
/*
FUNC: drawLine
PRE:  p1 AND p2 NOT NULL
POST: line segment represented by endpoints p1 and p2 will
be rendered to the current rendering buffer using the
current transformation matrix
*/
void  drawLine              (const point& p1,  const point& p2){
point t1, t2;
t1=transformPoint(p1);
t2=transformPoint(p2);
glBegin(GL_LINES);
glVertex3f(t1.x, t1.y, t1.z);
glVertex3f(t2.x, t2.y, t2.z);
glEnd();
}

/*
FUNC: shear<xy|xz|yz>
PRE:  none
POST: current transformation matrix will be sheared in the axis
specified (x and y, x and z, or y and z) by the coefficients
hx, hy, or hz
*/
void  shearxy               (const real hx,    const real hy){
matrix temp;
identMatrix(temp);
temp.a[0][2]=hx;
temp.a[1][2]=hy;
multMatrix(transMatrix, temp);
}

void  shearxz               (const real hx,    const real hz){
matrix temp;
identMatrix(temp);
temp.a[0][1]=hx;
temp.a[2][1]=hz;
multMatrix(transMatrix, temp);
}

void  shearyz               (const real hy,    const real hz){
matrix temp;
identMatrix(temp);
temp.a[1][0]=hy;
temp.a[2][0]=hz;
multMatrix(transMatrix, temp);
}

/*
FUNC: identMatrix
PRE:  none
POST: m is now 4X4 identity matrix
*/
void  identMatrix           (      matrix& m){
for(int y = 0; y < 4; ++y){
for(int x = 0; x < 4; ++x){
m.a[y][x] = 0;
}
m.a[y][y] = 1;
}
}

/*
FUNC: transformPoint
PRE:  p NOT NULL
POST: vertex p will be trasnformed by the current
transformation matrix
*/
point transformPoint        (const point& p){
point temp;
temp.x=transMatrix.a[0][0]*p.x + transMatrix.a[0][1]*p.y + transMatrix.a[0][2]*p.z + transMatrix.a[0][3];
temp.y=transMatrix.a[1][0]*p.x + transMatrix.a[1][1]*p.y + transMatrix.a[1][2]*p.z + transMatrix.a[1][3];
temp.z=transMatrix.a[2][0]*p.x + transMatrix.a[2][1]*p.y + transMatrix.a[2][2]*p.z + transMatrix.a[2][3];
return temp;
}

/*
FUNC: drawPoint
PRE:  p NOT NULL
POST: p will be rendered to the current rendering buffer
using the current transfomation matrix
*/
void  drawPoint             (const point& p){
point temp=transformPoint(p);
glBegin(GL_POINTS);
glVertex3f(temp.x, temp.y, temp.z);
glEnd();
}

/*
FUNC: initializeTransMatrix
PRE:  none
POST: transMatrix is now 4X4 identity matrix
*/
void  initializeTransMatrix (void){
identMatrix(transMatrix);
}

/*
FUNC: pushMatrix
PRE:  transMatrix has been initialized
POST: transMatrix pushed to top of transMatrixStack
*/
void  pushMatrix            (void){
node* temp=new node;
temp->m=transMatrix;
temp->n=transMatrixStack;
transMatrixStack=temp;
}
/*
FUNC: popMatrix
PRE:  transMatrixStack NOT EMPTY
POST: transMatrix replaced with top of transMatrixStack
transMatrixStock top replaced with transMatrixStack->n
*/
void  popMatrix             (void){
if(transMatrixStack != 0){
node* temp=transMatrixStack;
transMatrixStack=temp->n;
transMatrix=temp->m;
delete temp;
}
}
#endif

been working on this for about a month now, wanted to see what everyone thought, see if you notice anything out of place.
capn_midnight | Captain Midnight | deviantArt ACM | SIGGRAPH | Generation5

1. 1
Rutin
26
2. 2
3. 3
JoeJ
20
4. 4
5. 5

• 10
• 9
• 9
• 46
• 41
• ### Forum Statistics

• Total Topics
631750
• Total Posts
3002067
×