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]
Does this axis rotation code work?
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...
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 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
Popular Topics
Advertisement
Recommended Tutorials
Advertisement