user3204065
user3204065

Reputation: 51

OpenGL Object Rotation

I have an object drawn at (0, 0, 0) and the orientation of the object is (0, 0, 1). I am trying to rotate it to align with a vector, say, vi = (vx, vy, vz).

What I did is the following:

v = (0, 0, 1);
v_normal = (vnx, vny, vnz);

cross product to get the normal vector:

v_normal = v.cross(vi); 

Given the normal vector, I calculate the angles

thetax = arccos(vnx/length(v_normal))
thetay = arccos(vny/length(v_normal)) 
thetaz = arccos(vnz/length(v_normal))

and then i do the rotation:

glRotatedf(thetax, 1, 0, 0)
glRotatedf(thetay, 0, 1, 0)
glRotatedf(thetaz, 0, 0, 1).

After doing this, I got something weird. Could anyone explain how to get the angles for rotation after the cross product? Thanks!

Upvotes: 0

Views: 203

Answers (1)

Nicol Bolas
Nicol Bolas

Reputation: 474316

Every time you think that you need to rotate an object based on three axial rotations, stop! Find another way to solve your problem.

Take yours, for example. You start correctly: you get the cross-product between where the object is currently pointing and where you want it to point. That vector is the vector perpendicular to both of the other two. Which means... if you want to rotate between the two vectors, the cross product is the axis to rotate around.

glRotatef (there is no glRotate**df**. it's either f or d, not both) performs an angle-axis rotation. You give it an angle and the axis to rotate around. You just computed the axis; you merely need the angle between the original direction and the desired one.

That's trivial as well. By the nature of the cross-product, the length of the cross product vector is the sin of the angle between the two input vectors. So the angle is the inverse-sin of the length of the cross product.

auto v_axis = v.cross(vi);
auto angle = arcsin(length(v_axis));
glRotatef(angle, v_axis[0], v_axis[1], v_axis[2]);

You perform one rotation, not three.

Naturally, you need to account for the possibility that v and vi are pointing directly away from each other. In that case, the cross product will have a very small length. If the length of the cross product is very small, you basically need to pick some arbitrary vector that's perpendicular to one of them and then use an angle of 180 degrees.

Upvotes: 1

Related Questions