I have a direction vector that applied to a position gives me the point at which the camera should look. How can I get from that yaw, pitch and roll in order to use glRotatef properly?
Thanks in advance
I have a direction vector that applied to a position gives me the point at which the camera should look. How can I get from that yaw, pitch and roll in order to use glRotatef properly?
Thanks in advance
You probably don't actually want the yaw, pitch and roll. You just need the correct transformation. Try using gluLookAt
to build it. Documentation.
None of these equations are 'wrong' but all are a little clumsy. Ryder052, you example does not account certain cases as you've commented. Why not use atan2?
Given unit (normalized) direction vector d
pitch = asin(-d.Y);
yaw = atan2(d.X, d.Z)
pitch = asin(-d.Y);
I think this is wrong as for as vec2(x,z).length is not one –
African You cannot get yaw, pitch and roll from a direction vector as the direction vector will only tell which direction to look in (yaw and pitch)
To get the yaw and pitch you use trigonometry - I assume you have some working knowledge. Check out this wiki page for some useful diagrams to visualize the angles.
Letting Y = yaw, P = pitch.
First to get yaw you want:
tan(Y) = x/(-y)
Now to get pitch:
tan(P) = sqrt(x^2 + y^2)/z
To get the actual values for Y and P you'll need to use inverse tan, I've written it above using tan to make the derivation clearer.
Note that the minus signs depend on how you define you angles and axes, but you should get the idea.
You can then set roll to be 0 or whatever you like.
tan(P)
= distance-in-ground-plane / distance-along-up-axis
. As shown, z
is distance-along-up-axis, the sqrt(..)
is distance of 2D vector (x, y) in ground plane. Also note that in practice, using P = arctan(whatever)
won't give the correct sign for half the angles (have to compute sign separately, not shown); in practice, use atan2
. I think here it would be P = atan2(z, distance-in-ground-plane)
. Or switch the parameters if I'm wrong. –
Mantic You probably don't actually want the yaw, pitch and roll. You just need the correct transformation. Try using gluLookAt
to build it. Documentation.
pheelicks's equations are wrong. Dear future googlers, here you got what's working:
Assuming pitch: rotation by X axis, yaw: rotation by Y axis, roll: rotation by Z axis. Direction vector V(x,y,z)
pitch = asin(V.y / length(V));
yaw = asin( V.x / (cos(pitch)*length(V)) ); //Beware cos(pitch)==0, catch this exception!
roll = 0;
Well, I am not sure what any of these answers are about because I could not get any of them to work.
I created my own solution...
// get world target offset
// convert world target offset to world direction normal
// get my world transposed (inverted)
// rotate world direction normal to my space normal
Vector3D lWorldTargetOffset = gWorldTargetLocation - gWorldMyLocation;
Vector3D lWorldTargetDirection = lWorldTargetOffset.Normalize();
MatrixD lMyWorldTransposed = MatrixD.Transpose(MyWorldMatrix);
Vector3D lMySpaceTargetDirection = Vector3D.Rotate(lWorldTargetDirection, lMyWorldTransposed);
you now have the world target direction normal in my space
lMySpaceTargetDirection.X = pitch
lMySpaceTargetDirection.Y = yaw.
lMySpaceTargetDirection.Z = <0 infront >0 behind.
As per direction normals all values are -1 to 1 so if you want degrees simply * 90.
Not saying this is the best solution but it is the only one I could get to work after spending hours searching online and wading through copious amounts of obtuse and nebulous crud.
I hope you, someone, or anyone, will enjoy simply rotating the target direction normal making it relative to myspace, and find it easy and helpful :)
© 2022 - 2024 — McMap. All rights reserved.