Transformation

A.First Edition
This is simply a small tool to help me calculating the transformation matrix in graphic because I found myself hopeless in
matrix calculation. Both two simple translation matrix are wrong! Sometimes I just wonder what I can do without computer
and  programming?
B.The problem
Given a rotation axis in form of vector, and rotating angle in degree, can you generate the transformation matrix?
C.The idea of program
กก

There is no trick, no idea, simply matrix calculations.

D.The major functions
E.Further improvement
I found something I don't feel happy with VC++. Originally I want to define my generic Vector, Matrix by using template such
as:
template <class T, int size>
class Vector;
template<class T, int size>
class Matrix
{
public:
protected:
	Vector<T, size> rowVector[size]; //however, compiler reject such definition
	...
};
I guess VC++6.0 is using the low-level preprocessor so that it cannot deal with complicated template format, and it is also
the reason why it doesn't support template template which means template parameter is another template. This is solved in 
VC2003. But I don't have the privileged to enjoy the joy.
F.File listing
1. rotation.h
2. rotation.cpp
file name: rotation.h
enum AXIS {X_AXIS, Y_AXIS, Z_AXIS};

class Matrix;

class Vertex
{
public:
	Vertex(double x, double y, double z);
	double array[3];
};

class Vector
{
	friend class Matrix;
	//friend Vector operator*(const Vector& vect, double scalor);
public:
	double operator*(const Vector& other)const;
	Vector();
	Vector(double* otherArray);
	Vector operator*(double scalor) const;
	Vector(double d0, double d1, double d2);
	void clear();
	void display();
	double array[4];
	void normalize();

protected:
};

class Matrix
{
public:
	Matrix operator*(const Matrix& other);
	Vector operator*(const Vector& other);
	const Vector colVector(int index) const;
	void loadIdentity();
	Matrix();
	void translate(const Vector& vect);
	void translate(double d0, double d1, double d2);
	void rotate(AXIS axis, double degree);
	void rotate(const Vector& vect, double degree);
	void rotate(const Vector& vertex, const Vector& axis, double degree);
	void display();
protected:
	Vector rowVector[4];
};



file name: rotation.cpp
กก
#include <iostream>
#include <cmath>
#include "rotation.h"

using namespace std;
const double PI=3.14159;

double deg2rad(double degree)
{
	return degree/360.0*2*PI;
}
double rad2deg(double rad)
{
	return rad/2/PI*360;
}

Vertex::Vertex(double x, double y, double z)
{
	array[0]=x;
	array[1]=y;
	array[2]=z;
}

Vector Vector::operator *(double scalor)const
{
	Vector result=*this;
	for (int i=0; i<4; i++)
	{
		result.array[i]=array[i]*scalor;
	}
	return result;
}
/*
Vector operator*(const Vector& vect, double scalor)
{
	Vector result=vect;
	return result.operator *(scalor);
}
*/

//to do:
void Vector::normalize()
{
	double temp=0;
	int i;
	for (i=0; i<3; i++)
	{
		temp+=array[i]*array[i];
	}
	temp=sqrt(temp);
	if (temp!=0)
	{
		for (i=0; i<4; i++)
		{
		}
	}
}


double Vector::operator *(const Vector& other)const
{
	double result=0;
	for (int i=0; i<4; i++)
	{
		result+=array[i]*other.array[i];
	}
	return result;
}

Vector::Vector()
{
	clear();
	array[3]=1;
}

Vector::Vector(double d0, double d1, double d2)
{
	array[0]=d0;
	array[1]=d1;
	array[2]=d2;
	array[3]=1;
}

Vector::Vector(double* otherArray)
{
	for (int i=0; i<3; i++)
	{
		array[i]=otherArray[i];
	}
	array[3]=1;
}

void Vector::clear()
{
	for (int i=0; i<4; i++)
	{
		array[i]=0;
	}
}

const Vector Matrix::colVector(int index) const
{
	Vector result;
	for (int i=0; i<4; i++)
	{
		result.array[i]=rowVector[i].array[index];
	}
	return result;
}

void Vector::display()
{
	cout<<"\n\t(";
	for (int i=0; i<4; i++)
	{
		cout<<array[i];
		if (i!=3)
		{
			cout<<", ";
		}
	}
	cout<<")\n";
}

Matrix::Matrix()
{
	loadIdentity();
}

void Matrix::display()
{
	for(int i=0; i<4; i++)
	{
		rowVector[i].display();
	}
}

void Matrix::loadIdentity()
{
	for(int i=0; i<4; i++)
	{
		rowVector[i].clear();
		rowVector[i].array[i]=1;
	}
}


Matrix Matrix::operator *(const Matrix& other)
{
	Matrix result;
	for (int i=0; i<4; i++)
	{
		for (int j=0; j<4; j++)
		{
			result.rowVector[i].array[j]=rowVector[i]*other.colVector(j);
		}
	}
	return result;
}



void Matrix::translate(const Vector& vect)
{
	loadIdentity();
	for (int i=0; i<3; i++)
	{
		rowVector[i].array[3]=vect.array[i];
	}
}

void Matrix::translate(double d0, double d1, double d2)
{
	Vector vect(d0, d1, d2);
	translate(vect);	
}


void Matrix::rotate(enum AXIS axis, double degree)
{
	loadIdentity();
	double rad=deg2rad(degree);
	switch(axis)
	{
	case X_AXIS:
		rowVector[1].array[1]=cos(rad);
		rowVector[2].array[2]=cos(rad);
		rowVector[1].array[2]=-sin(rad);
		rowVector[2].array[1]=sin(rad);
		break;
	case Y_AXIS:
		rowVector[0].array[0]=cos(rad);
		rowVector[2].array[2]=cos(rad);
		rowVector[0].array[2]=sin(rad);
		rowVector[2].array[0]=-sin(rad);
		break;
	case Z_AXIS:
		rowVector[0].array[0]=cos(rad);
		rowVector[1].array[1]=cos(rad);
		rowVector[0].array[1]=-sin(rad);
		rowVector[1].array[0]=sin(rad);
		break;
	}
}

void Matrix::rotate(const Vector& vertex, const Vector& axis, double degree)
{
	Matrix matrixArray[3];
	Vector newVertex;
	newVertex=vertex*(-1.0);
	matrixArray[0].translate(vertex);
	matrixArray[1].rotate(axis, degree);
	matrixArray[2].translate(newVertex);
	for (int i=0; i<3; i++)
	{
		matrixArray[i].display();
	}
	*this=matrixArray[0]*matrixArray[1]*matrixArray[2];
}


void Matrix::rotate(const Vector& vect, double degree)
{
	double a,b,c,norm, d;
	Matrix matrixArray[5];
	a=vect.array[0];
	b=vect.array[1];
	c=vect.array[2];
	norm=sqrt(a*a+b*b+c*c);
	if (norm!=0)
	{
		a/=norm;
		b/=norm;
		c/=norm;
	}
	d=sqrt(b*b+c*c);
	//if it is not coincide with x_axis
	if (d!=0)
	{	
		matrixArray[0].rotate(X_AXIS, rad2deg(acos(c/d)));
	}
	matrixArray[1].rotate(Y_AXIS, rad2deg(acos(d)));
	matrixArray[2].rotate(Z_AXIS, degree);
	matrixArray[3].rotate(Y_AXIS, -rad2deg(acos(d)));
	if (d!=0)
	{
		matrixArray[4].rotate(X_AXIS, -rad2deg(acos(c/d)));
	}
	for (int i=0; i<3; i++)
	{
		matrixArray[i].display();
	}
	//(matrixArray[0]*matrixArray[1]).display();
	//cout<<"\n";
	*this=matrixArray[0]*matrixArray[1]*matrixArray[2]*matrixArray[3]
		*matrixArray[4];
}



int main()
{
	Matrix translate;
	Matrix rotate;
	Vector vertex(4,5,6), axis(3,2,5);

	rotate.rotate(vertex, axis, 45);
	rotate.display();
	//translate.display();


	return 0;
}
กก
an output is like this(with debug information attached):

(1, 0, 0, 0)

(0, 0.928477, -0.371391, 0)

(0, 0.371391, 0.928477, 0)

(0, 0, 0, 1)

(0.873589, 0, 0.486664, 0)

(0, 1, 0, 0)

(-0.486664, 0, 0.873589, 0)

(0, 0, 0, 1)

(0.707107, -0.707106, 0, 0)

(0.707106, 0.707107, 0, 0)

(0, 0, 1, 0)

(0, 0, 0, 1)

(1, 0, 0, 4)

(0, 1, 0, 5)

(0, 0, 1, 6)

(0, 0, 0, 1)

(0.776477, -0.619785, -0.1138, 0)

(0.527293, 0.737938, -0.4212, 0)

(0.345031, 0.267046, 0.8998, 0)

(0, 0, 0, 1)

(1, 0, 0, -4)

(0, 1, 0, -5)

(0, 0, 1, -6)

(0, 0, 0, 1)

(0.776477, -0.619785, -0.1138, 4.67582)

(0.527293, 0.737938, -0.4212, 1.72834)

(0.345031, 0.267046, 0.8998, -2.11416)

(0, 0, 0, 1)
Press any key to continue


                                 back.gif (341 bytes)       up.gif (335 bytes)         next.gif (337 bytes)