Advertisement

Does this axis rotation code work?

Started by July 21, 2003 10:10 AM
0 comments, last by Promit 21 years, 7 months ago
I have this code for rotating a point around an arbitrary axis, which I wrote based on a tutorial I read. I'm getting really funky results, though, and this code is what seems to be giving incorrect results...

void MatrixRotationAxis( Matrix& MatOut, const Vector& Axis, float Angle )
{
	//copy the axis

	Vector v = Axis;

	//first, rotate the axis into the YZ plane

	//length of projection of axis onto XZ plane; 0 means it is already in YZ

	float Len1;
	Len1 = (float) sqrt( v.x * v.x + v.z * v.z );

	Matrix R1;
	float Sin1, Cos1;

	if( Len1 > 0 )
	{
		Cos1 = v.z / Len1;
		Sin1 = v.x / Len1;

		MatrixIdentity( R1 );
		R1[0] = Cos1;
		R1[2] = - Sin1;
		R1[8] = Sin1;
		R1[10] = Cos1;
	}
	else
	{
		MatrixIdentity( R1 );
	}

	//now, rotate axis around X-axis into Z axis

	//length of projection of axis onto Z-axis

	float Len2;
	Len2 = (float) sqrt( v.y * v.y + v.z * v.z );
	
	Matrix R2;
	float Sin2, Cos2;

	if( Len2 > 0 )
	{
		Cos2 = v.z / Len2;
		Sin2 = v.y / Len2;

		MatrixIdentity( R2 );
		R2[5] = Cos2;
		R2[6] = - Sin2;
		R2[9] = Sin2;
		R2[10] = Cos2;
	}
	else
	{
		//should never happen

		MatrixIdentity( R2 );
	}

	//do a rotation around z

	Matrix R3;
	MatrixRotationZ( R3, Angle );

	Matrix R2Inv;
	//now reverse previous transform into Z axis

	if( Len2 > 0 )
	{
		MatrixIdentity( R2Inv );
		R2Inv[5] = Cos2;
		R2Inv[6] = Sin2;
		R2Inv[9] = - Sin2;
		R2Inv[10] = Cos2;
	}

	Matrix R1Inv;
	if( Len1 > 0 )
	{
		MatrixIdentity( R1Inv );
		R1Inv[0] = Cos1;
		R1Inv[2] = Sin1;
		R1Inv[8] = -Sin1;
		R1Inv[10] = Cos1;
	}

	//multiply everything together into the final matrix

        //R1 * R2 * R3 * R2Inv * R1Inv

	MatrixMult( MatOut, R1, R2 );
	MatrixMult( MatOut, MatOut, R3 );
	MatrixMult( MatOut, MatOut, R2Inv );
	MatrixMult( MatOut, MatOut, R1Inv );
}
Matrix is simply typedef'ed to be a float[16]. Vector is a struct { float x, y, z; };. Assume that MatrixMult and MatrixIdentity work fine. Is there anything specifically wrong with the code, or is it just totally mangled, or what? I understand sections of it, but as a whole, I don't really get it, especially the last multiplication. P.S. The matrices are OpenGL column major. [edited by - Promit on July 21, 2003 11:28:18 AM]
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
I sure that it don''t do ange axis rotation. It look like some euler angle conversion .

this look much simpler

matrix33 FromAxisAngle( const vector3& axis, float angle )
{

vector3 v(axis);
v.norm();
float sa = (float) sin(angle);
float ca = (float) cos(angle);

vector3 vs(v*sa);
vector3 vt(v*(1.0f - ca));

matrix33 rotM;
rotM.M11 = vt.x * v.x + ca;
rotM.M22 = vt.y * v.y + ca;
rotM.M33 = vt.z * v.z + ca;

vt.x *= v.y;
vt.z *= v.x;
vt.y *= v.z;

rotM.M12 = vt.x - vs.z;
rotM.M13 = vt.z + vs.y;
rotM.M21 = vt.x + vs.z;
rotM.M23 = vt.y - vs.x;
rotM.M31 = vt.z - vs.y;
rotM.M32 = vt.y + vs.x;
return rotM;
}

This topic is closed to new replies.

Advertisement