# Chaining quaternion rotations

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

## Recommended Posts

Hey all,

I'm trying to convert two axis rotations into Quaternion rotations. When I constrain the rotations to one axis i can get it to work properly, but it requires I multiply it by a second quaternion of 90degres to get it to work. Note, this code doesn't compile, I will have the whichever two I'm not using commented out when running.

 if(cameraXRotate > 180) { mult = -1; } /* rotation around the x axis*/ Quaternion cameraX = new Quaternion(mult * cameraXRotate * (float)(Math.PI / 180.0), new XYZ(1,0,0)); Quaternion camera = new Quaternion(90 * (float) (Math.PI / 180.0), new XYZ(0, 1, 0)); /* Rotation around the y axis*/ Quaternion cameraY = new Quaternion(-cameraYRotate * (float) (Math.PI / 180.0), new XYZ(0, 1, 0)); Quaternion camera = new Quaternion(90 * (float) (Math.PI / 180.0), new XYZ(1, 0, 0)); /* rotation around the z axis*/ Quaternion cameraZ = new Quaternion(cameraZRotate * (float)(Math.PI / 180.0), new XYZ(0,0,1)); Quaternion camera = new Quaternion(90 * (float) (Math.PI / 180.0), new XYZ(1, 0, 0)); 

Now, firstly, I'm not sure why I have to multiply by 90 to get all these to work, and I'm not sure why I have to reverse the rotation on the X axis if it's greater than 180. All I know, is that these seem to work properly on single axis rotation.

This is the standard rotation code in openGL for the cameraX and Y, the negative cameraX is deliberate-
 glRotatef(-cameraXRotate, 1, 0, 0); glRotatef(cameraYRotate, 0, 1, 0); 

Now, when I try to multiple the two rotations together, I get weird angles. This is my rotation code:

 /* x axis rotation */ Quaternion cameraX = new Quaternion(mult * cameraXRotate * (float)(Math.PI / 180.0), new XYZ(1,0,0)).mul(new Quaternion(90 * (float)(Math.PI / 180.0), new XYZ(1,0,0))); /* y axis rotation */ Quaternion cameraY = new Quaternion(cameraYRotate * (float) (Math.PI / 180.0), new XYZ(0, 1, 0)).mul(new Quaternion(90 * (float)(Math.PI / 180.0), new XYZ(1,0,0))); Quaternion result = Quaternion.IDENTITY.mul(cameraX.mul(cameraY)); 

Any ideas? I'm really stuck on this one

Thanks!

##### Share on other sites
The quaternion corresponding to a rotation of alpha around the axis (x,y,z) is

q = cos(alpha/2) + sin(alpha/2)*(xi+yj+zk)

I don't see cos(alpha/2) and sin(alpha/2) anywhere in your code, so it's probably not right.

This is roughly how I would do it:
#include <iostream> #include <cmath> #include <boost/math/quaternion.hpp> typedef boost::math::quaternion<double> Q; struct Vector3 { double x, y, z; Vector3(double x, double y, double z) : x(x), y(y), z(z) { } }; std::ostream &operator<<(std::ostream &os, Vector3 const &v) { return os << '(' << v.x << ',' << v.y << ',' << v.z << ')'; } Q axis_and_angle_to_quaternion(double angle, Vector3 axis) { double sin_angle_halfs = std::sin(angle * 0.5); return Q(std::cos(angle * 0.5), sin_angle_halfs*axis.x, sin_angle_halfs*axis.y, sin_angle_halfs*axis.z); } Vector3 apply(Q q, Vector3 v) { Q r = q * Q(0, v.x, v.y, v.z) * conj(q); return Vector3(r.R_component_2(), r.R_component_3(), r.R_component_4()); } int main() { double const degrees = std::atan(1.0)/45.0; Q rx = axis_and_angle_to_quaternion(90*degrees, Vector3(1,0,0)); Q ry = axis_and_angle_to_quaternion(90*degrees, Vector3(0,1,0)); Q r = rx*ry; std::cout << apply(r, Vector3(1,2,3)) << '\n'; } 

1. 1
2. 2
Rutin
19
3. 3
khawk
18
4. 4
5. 5

• 9
• 12
• 16
• 26
• 10
• ### Forum Statistics

• Total Topics
633769
• Total Posts
3013758
×