How to get Yaw, Pitch, and Roll from a Matrix?

Is this correct? If now can you post what would be?

this is the site I’m getting my formulas from: http://planning.cs.uiuc.edu/node103.html


float yaw = (float) -(Math.tan(m.m10/m.m00));
        float pitch = (float) -(Math.tan((-m.m20)/(Math.sqrt(Math.pow(m.m21, 2) + Math.pow(m.m22, 2)))));
        float roll = (float) -(Math.tan(m.m21/m.m22));

Hi

Take a look at the source for Java3D or Ardor3d, they will do the maths in there somewhere, for ardor it’s done using quaternions, which can be calculated from a matrix and then converted to euler angles.

HTH

Endolf

Euler angles: Just say no (at runtime). Seriously, they aren’t interesting unless you’re doing some specific types of integration.

Want to improved speed? If not: Do you want to improve your accuracy? If yes to at least one, then:

Math.pow(x,2) -> x*x
Math.sqrt(Math.pow(x,2)) -> Math.abs(x)

If you still decide to use Euler angles, then note that most references will be for right-handed coordinate frames (instead of OpenGL’s left-handed).

Unless you are doing simple rotations with them (land vehicles) you’re best off using quaternions.

I’m no mathematician, see here for some discussion.

Endolf

You forgot the + between the two Pow calls.

Math.sqrt(Math.pow(m.m21, 2) + Math.pow(m.m22, 2))

Also is there a way to use quaternions from a openGL call, or a matrix to move/rotate?

Alright, this is what I got so far, but my camera doesn’t seem to move at all. Even if I put lookAt on (5,50,5) it stays looking foward. This is my code so far:


import org.lwjgl.opengl.GL11;
import org.lwjgl.util.vector.Matrix3f;
import org.lwjgl.util.vector.Vector3f;

public class Camera {
	 //3d vector to store the camera's position in
    Vector3f position = null;
    Vector3f lookAt = null;
    Vector3f up = null;
    //the rotation around the Y axis of the camera
    float yaw = 0;
    
    //the rotation around the X axis of the camera
    float pitch = 0;
    
    //the rotation around the Z axis of the camera
    float roll = 0;
    
    public Camera(float x, float y, float z)
    {
        //instantiate position Vector3f to the x y z params.
        position = new Vector3f(x, y, z);
        lookAt = new Vector3f();
        up = new Vector3f(0,1,0);
    }
    
    public void lookThrough()
    {
    	Matrix3f m = new Matrix3f();
    	
    	
    	up = new Vector3f(0,1,0);
    	Vector3f out = new Vector3f();
    	Vector3f.sub(position, lookAt, out);
    	out.normalise();
    	Vector3f.sub(up, (Vector3f) out.scale(Vector3f.dot(out,up)), up);
    	
    	Vector3f camUp = new Vector3f();
    	Vector3f.sub(up , (Vector3f) out.scale(Vector3f.dot(out,up)), camUp);
    	//set forward vector
    	m.m00 = 0;
    	m.m01 = 0;
    	m.m02 = 1;
    	
    	//set right vector
    	m.m10 = 1;
    	m.m11 = 0;
    	m.m12 = 0;
    	
    	//set up vector
    	m.m20 = camUp.x;
    	m.m21 = camUp.y;
    	m.m22 = camUp.z;
    	
    	if(m.m00 != 0)
    		yaw = (float) Math.atan2((-m.m20),(Math.sqrt(Math.pow(m.m21, 2) + Math.pow(m.m22, 2))));
    	else 
    		yaw = 0;
    	
    	pitch = (float) Math.atan2(m.m21,m.m22);
    	
    	if(m.m22 != 0)
    		roll =  (float) Math.atan2(m.m10,m.m00);
    	else
    		roll = 0;
    	
    	System.out.println("roll: " + roll + " pitch: " + pitch + " yaw: " + yaw);
    	
        //roatate the pitch around the X axis
        GL11.glRotatef(pitch, 1.0f, 0.0f, 0.0f);
        //roatate the yaw around the Y axis
        GL11.glRotatef(yaw, 0.0f, 1.0f, 0.0f);
        //roatate the yaw around the Y axis
        GL11.glRotatef(roll, 0.0f, 0.0f, 1.0f);
        //translate to the position vector's location
        GL11.glTranslatef(position.x, position.y, position.z);
    }
}


And this is my output:


roll: 1.5707964 pitch: 2.819842 yaw: 0.0
roll: 1.5707964 pitch: 2.819842 yaw: 0.0
roll: 1.5707964 pitch: 2.819842 yaw: 0.0
roll: 1.5707964 pitch: 2.819842 yaw: 0.0
roll: 1.5707964 pitch: 2.819842 yaw: 0.0
roll: 1.5707964 pitch: 2.819842 yaw: 0.0
roll: 1.5707964 pitch: 2.819842 yaw: 0.0
roll: 1.5707964 pitch: 2.819842 yaw: 0.0
roll: 1.5707964 pitch: 2.819842 yaw: 0.0
roll: 1.5707964 pitch: 2.819842 yaw: 0.0
roll: 1.5707964 pitch: 2.819842 yaw: 0.0
roll: 1.5707964 pitch: 2.819842 yaw: 0.0
roll: 1.5707964 pitch: 2.819842 yaw: 0.0
roll: 1.5707964 pitch: 2.819842 yaw: 0.0
roll: 1.5707964 pitch: 2.819842 yaw: 0.0
roll: 1.5707964 pitch: 2.819842 yaw: 0.0
roll: 1.5707964 pitch: 2.819842 yaw: 0.0
roll: 1.5707964 pitch: 2.819842 yaw: 0.0
roll: 1.5707964 pitch: 2.819842 yaw: 0.0
roll: 1.5707964 pitch: 2.819842 yaw: 0.0
roll: 1.5707964 pitch: 2.819842 yaw: 0.0
roll: 1.5707964 pitch: 2.819842 yaw: 0.0
roll: 1.5707964 pitch: 2.819842 yaw: 0.0
roll: 1.5707964 pitch: 2.819842 yaw: 0.0
roll: 1.5707964 pitch: 2.819842 yaw: 0.0
roll: 1.5707964 pitch: 2.819842 yaw: 0.0
roll: 1.5707964 pitch: 2.819842 yaw: 0.0


Yaw should be at something aside of 0, right?

m.m00 = 0;
if(m.m00 != 0)...;else yaw = 0;

do you see?

I’m pretty sure OpenGL is right-handed, they just do some weirdness where the camera looks down the negative z-axis.

You’re correct. It’s Direct X that uses a left handed coordinate frame…shame on me.