<html>

<head><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- MyFirstUnitAd -->
<ins class="adsbygoogle"
     style="display:inline-block;width:970px;height:250px"
     data-ad-client="ca-pub-5778386704669218"
     data-ad-slot="1503492166"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>

<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 6.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>transformation matrix</title>
</head>

<body>



<p align="center"><span lang="en-ca"><font size="6" color="#FF0000"><b>
Transformation</b></font></span></p>

<div align="left">
  <pre><b><font color="#ff0000" size="5">A.<span lang="en-ca">First</span> Edition</font></b></pre>
</div>
<div align="left">
  <pre><b>This is<span lang="en-ca"> </span></b><span lang="en-ca"><b>simply a small tool to help me calculating the transformation matrix in graphic because I found myself hopeless in</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>matrix calculation. Both two simple translation matrix are wrong! Sometimes I just wonder what I can do without computer</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>and  programming?</b></span></pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">B</span>.<span lang="en-ca"><a name="problem"></a>The problem</span></font></b></pre>
</div>
<div align="left">
	<pre><span lang="en-ca"><b>Given a rotation axis in form of vector, and rotating angle in degree, can you generate the transformation matrix?</b></span></pre>
</div>
<div align="left">
  <b><font color="#ff0000" size="5"><span lang="en-ca">C</span>.<span lang="en-ca">The
  </span></font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>idea of 
  program</b></font></span></div>
<div align="left">
  กก</div>
<p><span lang="en-ca"><font size="2"><b>There is no trick, no idea, simply 
matrix calculations.</b></font></span></p>
<div align="left">
  <pre><b><font color="#ff0000" size="5">D.<span lang="en-ca"><a name="Method"></a>The </span>major functions</font></b></pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">E</span>.</font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>Further improvement</b></font></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><font size="2"><b>I found something I don't feel happy with VC++. Originally I want to define my generic Vector, Matrix by using template such</b></font></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>as:</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>template &lt;class T, int size&gt;</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>class Vector;</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>template&lt;class T, int size&gt;</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>class Matrix</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>{</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>public:</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>protected:</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>	Vector&lt;T, size&gt; rowVector[size]; //however, compiler reject such definition</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>	...</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>};</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>I guess VC++6.0 is using the low-level preprocessor so that it cannot deal with complicated template format, and it is also</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>the reason why it doesn't support template template which means template parameter is another template. This is solved in </b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>VC2003. But I don't have the privileged to enjoy the joy.</b></span></pre>
</div>
<div align="left">
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">F</span>.</font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>File listing</b></font></span></pre>
</div>
<div align="left" style="width: 898; height: 86">
  <pre><font size="3"><b><span lang="en-ca">1. rotation</span>.<span lang="en-ca">h</span></b></font></pre>
  <pre><span lang="en-ca"><font size="3"><b>2</b></font></span><font size="3"><b><span lang="en-ca">. rotation</span>.</b></font><span lang="en-ca"><font size="3"><b>cpp</b></font></span></pre>
</div>
  <pre><font size="3" color="#FF0000"><b><span lang="en-ca">file name: rotation.h</span></b></font></pre>
</div>
<pre>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&amp; vect, double scalor);
public:
	double operator*(const Vector&amp; 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&amp; other);
	Vector operator*(const Vector&amp; other);
	const Vector colVector(int index) const;
	void loadIdentity();
	Matrix();
	void translate(const Vector&amp; vect);
	void translate(double d0, double d1, double d2);
	void rotate(AXIS axis, double degree);
	void rotate(const Vector&amp; vect, double degree);
	void rotate(const Vector&amp; vertex, const Vector&amp; axis, double degree);
	void display();
protected:
	Vector rowVector[4];
};


</pre>
<pre>

</pre>
<pre><font size="3" color="#FF0000"><b><span lang="en-ca">file name: rotation</span>.<span lang="en-ca">cpp</span></b></font></pre>
<pre>กก</pre>
<pre>#include &lt;iostream&gt;
#include &lt;cmath&gt;
#include &quot;rotation.h&quot;

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&lt;4; i++)
	{
		result.array[i]=array[i]*scalor;
	}
	return result;
}
/*
Vector operator*(const Vector&amp; vect, double scalor)
{
	Vector result=vect;
	return result.operator *(scalor);
}
*/

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


double Vector::operator *(const Vector&amp; other)const
{
	double result=0;
	for (int i=0; i&lt;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&lt;3; i++)
	{
		array[i]=otherArray[i];
	}
	array[3]=1;
}

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

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

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

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

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

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


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



void Matrix::translate(const Vector&amp; vect)
{
	loadIdentity();
	for (int i=0; i&lt;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&amp; vertex, const Vector&amp; 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&lt;3; i++)
	{
		matrixArray[i].display();
	}
	*this=matrixArray[0]*matrixArray[1]*matrixArray[2];
}


void Matrix::rotate(const Vector&amp; 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&lt;3; i++)
	{
		matrixArray[i].display();
	}
	//(matrixArray[0]*matrixArray[1]).display();
	//cout&lt;&lt;&quot;\n&quot;;
	*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;
}</pre>
<pre>กก</pre>
<pre><font color="#FF0000"><b><span lang="en-ca">an output is like this(with debug information attached):</span></b></font></pre>
<pre><span lang="en-ca">
(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</span>
</pre>
<pre>
</pre>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                                   
&nbsp;&nbsp;&nbsp; <a href="WhoAmI.htm">                  







                       <img src="picture/back.gif" style="border: medium none" alt="back.gif (341 bytes)" width="32" height="35"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
<a href="index.htm"><img src="picture/up.gif" style="border: medium none" alt="up.gif (335 bytes)" width="35" height="32"></a>       &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                         
<img src="picture/next.gif" style="border: medium none" alt="next.gif (337 bytes)" width="32" height="35">          


</p>

</body>

</html>