# Set rotation on single axis with provided angle using Quaternion

I am using a Quaternion to represent the rotation of some object, and I would like to allow the user to rotate it about a single axis at a time using textbox, so he would write the angle that the object is rotated by (ex. at X-axis), then the object rotation is set to that rotation.
I know that, this operation q1 * q will rotate q by q1, but I don't know how to set the rotation at a single axis, Could any one help me to complete this function?

public void SetRotationX(float Angle)
{

}


Based on your function naming, I take it your just trying to set the rotation to a completely new rotation along that angle, as opposed to offsetting the rotation by a set amount.

In this case, rather than concatenating a quaternion to the current one, you can just create a new quaternion entirely. Note that you'll still probably want to pass in an x, y and z value to the function, relating to the other text boxes, or the current rotations along those angles.

Here are the outlines for the formulae to working out each axis of a quaternion, assuming no prior code is in place to create these Euler conversions already (note, pseudocode to avoid language issues):

void EulerAnglesToQuaternion( Quaternion q , double x , double y , double z )
{
double cx = cos(x*0.5);
double cy = cos(y*0.5);
double cz = cos(z*0.5);
double sx = sin(x*0.5);
double sy = sin(y*0.5);
double sz = sin(z*0.5);

q.w = (cz*cx*cy)+(sz*sx*sy);
q.x = (cz*sx*cy)-(sz*cx*sy);
q.y = (cz*cx*sy)+(sz*sx*cy);
q.z = (sz*cx*cy)-(cz*sx*sy);
}

• I will try this as soon as possible, thanks Joeb Rogers – O-BL Sep 18 '17 at 9:59

Going from the definition of quaternions as 3D rotations, we can represent a rotation about an arbitrary 3D axis by taking a unit vector in that direction, scaling it by the sine of half the angle of rotation, and using it as the 3 imaginary components of a quaternion. The remaining real component is then the cosine of half the angle, to keep the quaternion of unit length.

Quaternion AngleAxis(Vector3 axis, float angle) {

Vector3 imaginary = axis.normalized * sin(angle/2f);

Quaternion q;
q.x = imaginary.x;
q.y = imaginary.y;
q.z = imaginary.z;

q.w = cos(angle/2f);

return q;
}


Rotating around just the x axis is then a simple special case:

Quaternion RotationAroundX(float angle) {

// Equivalent to AngleAxis(new Vector3(1, 0, 0), angle)

Quaternion q;
q.x = sin(angle/2f);
q.y = 0f;
q.z = 0f;
q.w = cos(angle/2f);

return q;
}

• Thanks DMGregory, when I am rotating around a single axis I have a pre-rotated object, so I cannot do it that simple. – O-BL Sep 18 '17 at 9:52
• void RotationAroundX(Quaternion q, float Angle) {//implementation... } – O-BL Sep 18 '17 at 9:54
• What about this case, where you have whatever rotation represented by quaternion and you want to set the rotation on a single axis? – O-BL Sep 18 '17 at 9:56
• It sounds like you expect to be able to change just the "x part" of a rotation, independent of what's happened on the other axes, the way you might do by setting just one component of a translation vector while leaving the others untouched. Rotations don't work this way - their result is always dependent on the order in which the rotations are applied. So to pull out the "X part" of a quaternion, we need to know what other rotations were applied after X, or recompose the quaternion from the updated contributing rotations. – DMGregory Sep 18 '17 at 10:04
• Could you provide a mathematical equations please? – O-BL Sep 18 '17 at 10:08