Rotate an object given axis-angle given two vectors...

Started by
1 comment, last by Kuroyume0161 16 years ago
I'm having a ball trying to get this to work. Here are the givens: There is a bone object which points down the +Z AXIS and is at the origin. I have a vector which describes where the bone should be pointing (relative to the origin). The obvious way to rotate the bone is to get the angle between two vectors. The one vector would be (0,0,1) for the bone and the other vector as given. Then I need to get the axis through which to rotate by angle. This would be the normal to the plane in which the two vectors lie. The code, as best I can find, is: Vector v1 = Vector(0.0f,0.0f,1.0f); Vector v2 = !epBB; // '!' normalizes vector operator Vector axis = v1%v2; // '%' is cross product operator Real angle = VectorAngle(v1, v2); // Angle between two vectors // Signed 3D angle between two vectors: atan2(dot(normal,cross(v1,v2)), dot(v1,v2)) Matrix bm; if (Abs(angle) < 0.00001f) bm = MatrixScale(Vector(epBBlen)); else bm = RotAxisToMatrix(!axis, angle) * MatrixScale(Vector(epBBlen)); This is failing in both angle AND axis. First, the cross product with an orthonormal vector is the same vector as the other with the one axis (1.0f) zeroed. So, v1 x v2 = (v2.x, v2.y, 0). That is useless - it isn't perpendicular to the plane containing them. What the f...? Maybe someone could illuminate how to go about doing this correctly? Thanks, Robert
Advertisement
First of all, you should give this thread a read, especially the parts related to operator overloading in math libraries.

Meanwhile though, here's the take-away: don't abuse operator overloading, and don't use overloads whose meaning is not obvious (the simple fact that you had to add comments explaining what the operators do says more on the subject than I ever could :).

I'm not quite sure what's going on in your code, but here's one way to do it:
vector3 axis = cross(v1, v2);float l = length(axis);float angle = atan2(l, dot(v1,v2));matrix33 rotation = identity33();if (l > epsilon) {    rotation.make_rotation(normalize(axis), angle));}
I'm not sure that you need to compute the sign of the rotation separately - that should fall out naturally from the direction in which the cross product (axis of rotation) points.
Unfortunately, the Vector class and its operators aren't mine - they are part of an existing SDK.

What I found is that swapping v1 and v2 in the cross product (i.e.: v2%v1) removed an anomaly with creating the normal (you can do the math quickly to see what happens if the orthonormal vector is first). Very odd that.

Subsequently, they were swapped in the VectorAngle() call.

The swaps fixed the problems. Maybe it is a difference in the method/operator coding that requires this (?).

Yes, I had previously tried the length*axis approach for the atan2() angle calculation. It may work now that this anomaly has been circumvented.

Thank you very much,
Robert

This topic is closed to new replies.

Advertisement