# Rotating a quaternion around an axis...

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

## Recommended Posts

I thought I had this right, but some testing has given unwanted results. Here is what I have:
// camera forwards the calls to its quaternion

//------------------------------------------------
//------------------------------------------------
void Quaternion::RotateYaw(float a_theta)
{
Vector3 l_axis_y;
GetAxisY(l_axis_y);			// gets this quaternions Y-axis

RotateAroundAxis(a_theta, &l_axis_y);
}

//------------------------------------------------
//------------------------------------------------
void Quaternion::RotatePitch(float a_theta)
{
Vector3 l_axis_x;
GetAxisX(l_axis_x);			// gets this quaternions X-axis

RotateAroundAxis(a_theta, &l_axis_x);
}

//------------------------------------------------
//------------------------------------------------
void Quaternion::RotateAroundAxis(float a_theta, const Vector3* a_axis)
{
Quaternion l_quat;

l_quat.x = a_axis->x * sin(a_theta * 0.5f);
l_quat.y = a_axis->y * sin(a_theta * 0.5f);
l_quat.z = a_axis->z * sin(a_theta * 0.5f);
l_quat.w = cos(a_theta * 0.5f);

(*this) *= l_quat;
}


This code I would have expected to work like normal euler angle rotation, and the result should have been a camera pitched slightly, without any tilt. But there is a tilt (http://www.mercenaries.ws/tiltedquat.jpg), which I don't understand. When I rotateYaw() alone, I have no problem. I always have a problem with pitch, however, no matter if I do pitch alone or not, or in what order I call it. What am I doing wrong? Edit: Oh, btw, I will provide the GetX(), GetY() and GetZ() methods as well, just in case it will become interesting.
//------------------------------------------------
//------------------------------------------------
void Quaternion::GetAxisX(Vector3& a_axis_x) const
{
//Real fTx  = 2.0*x;
float fTy  = 2.0f*y;
float fTz  = 2.0f*z;
float fTwy = fTy*w;
float fTwz = fTz*w;
float fTxy = fTy*x;
float fTxz = fTz*x;
float fTyy = fTy*y;
float fTzz = fTz*z;

a_axis_x.Set(1.0f-(fTyy+fTzz), fTxy+fTwz, fTxz-fTwy);
}

//------------------------------------------------
//------------------------------------------------
void Quaternion::GetAxisY(Vector3& a_axis_y) const
{
float fTx  = 2.0f*x;
float fTy  = 2.0f*y;
float fTz  = 2.0f*z;
float fTwx = fTx*w;
float fTwz = fTz*w;
float fTxx = fTx*x;
float fTxy = fTy*x;
float fTyz = fTz*y;
float fTzz = fTz*z;

a_axis_y.Set(fTxy-fTwz, 1.0f-(fTxx+fTzz), fTyz+fTwx);
}

//------------------------------------------------
//------------------------------------------------
void Quaternion::GetAxisZ(Vector3& a_axis_z) const
{
float fTx  = 2.0f*x;
float fTy  = 2.0f*y;
float fTz  = 2.0f*z;
float fTwx = fTx*w;
float fTwy = fTy*w;
float fTxx = fTx*x;
float fTxz = fTz*x;
float fTyy = fTy*y;
float fTyz = fTz*y;

a_axis_z.Set(fTxz+fTwy, fTyz-fTwx, 1.0f-(fTxx+fTyy));
}



##### Share on other sites
Isn't this line incorrect:

(*this) *= l_quat;

When you rotate a quaternion P by a quaternion l_quat, the result should be:

l_quat * P * l_quat_conj

Where l_quat_conj is the quaternion conjugate of l_quat:

http://mathworld.wolfram.com/QuaternionConjugate.html

(Or perhaps I've overlooked something?)

##### Share on other sites
Your answer got me thinking, and I looked into the line you mentioned, and I remmebered that quaternion multiplication is not commutative. Do'h!

I tried to invert the multiplication order, and it seemed to fix the problem.

(*this) = l_quat * *this;

Thanx alot.

1. 1
2. 2
Rutin
22
3. 3
4. 4
JoeJ
17
5. 5

• 14
• 30
• 13
• 11
• 11
• ### Forum Statistics

• Total Topics
631774
• Total Posts
3002297
×