# Euler angles to Cartesian Coordinates for use with gluLookAt

I have searched all of the internet but just couldn't find the answer. I am using LibGDX and this is part of my code that loops over and over:

``````public void render()
{
GL11 gl = Gdx.gl11;

float centerX = (float)Math.cos(yaw) * (float)Math.cos(pitch);
float centerY = (float)Math.sin(yaw) * (float)Math.cos(pitch);
float centerZ = (float)Math.sin(pitch);
System.out.println(centerX+" "+centerY+" "+centerZ+" ~ "+GDXRacing.camera.position.x+" "+GDXRacing.camera.position.y+" "+GDXRacing.camera.position.z);
Gdx.glu.gluLookAt(gl, GDXRacing.camera.position.x, GDXRacing.camera.position.y, GDXRacing.camera.position.z, centerX, centerY, centerZ, 0, 1, 0);

if(Gdx.input.isKeyPressed(Keys.A))
{
yaw--;
}
if(Gdx.input.isKeyPressed(Keys.D))
{
yaw++;
}
}
``````

I might just be bad at the math, but I dont get it. Does someone have a good explanation and an idea about how to deal with this? I am trying to make a first person camera. By the way, the camera is translated by +10 on the Z axis. Currently when I run the application, this is what I get:

Watch video in browser | Download video (for those who cant download the video, everything shakes in a clockwise/anticlockwise action, depending on if I increase or decrease the Yaw value)

-Thank you.

I fixed it and posted an answer below if you want to see how I did it. This would have not been possible without Sam Hocevar's answer, so big props to him :D

-

If you are making a first person camera, the center of the scene must rotate around the camera. So the vector you are building from `yaw` and `pitch` must be added to the camera position.

For the first code snippet:

• use smaller increments for `yaw` and `pitch`, because `sin()` and `cos()` use radians, not degrees
• in the `gluLookAt` call, replace `centerX` with `GDXRacing.camera.position.x + centerX` and same for Y and Z.
-
OH MY GOD, SUCH A SIMPLE ANSWER :O. I seriously feel like an idiot :S. Thanks for the tip. To keep things simple for now, I only used the yaw in this test: pastebin.com/kASqL887 . Now either my field of view is set too high or i did something else wrong because it looks as if it was a third person view. But thanks for the hint :) – notro Jul 9 '12 at 20:48
@notrodash also, you should rename these `center` variables to `direction` or something, because that better indicates what they are. – sam hocevar Jul 9 '12 at 21:04
Here is an example of what I mean (video) Link to cl.ly drop, you can play the video from there. Just as recommended, my resize method looks like this pastebin.com/8hcZ02RL . What now? – notro Jul 9 '12 at 21:05
@notrodash the camera code now looks correct, but it’s possible that you are rotating your scene objects in addition to the camera itself by pushing matrices in the wrong order or not resetting the matrix stack when it should. – sam hocevar Jul 9 '12 at 21:23
But if I rotate the scene, then wouldn't it look like I am not moving at all? I will look into it and check what's wrong. If I place the camera at the origin, I don't get this effect. I always thought that gluLookAt only affected the camera. – notro Jul 10 '12 at 6:21

Thanks to Sam Hocevar's excellent answer I was able to write this:

``````public void render()
{
float centerX = (float)(MathUtils.sinDeg(yaw)) * Gdx.graphics.getDeltaTime();
float centerY = (float)(MathUtils.sinDeg(pitch) / MathUtils.cosDeg(pitch) * Gdx.graphics.getDeltaTime());
float centerZ = (float)(-MathUtils.cosDeg(yaw)) * Gdx.graphics.getDeltaTime();

Gdx.glu.gluLookAt(Gdx.gl11, GDXRacing.camera.position.x, GDXRacing.camera.position.y, GDXRacing.camera.position.z, GDXRacing.camera.position.x+centerX, GDXRacing.camera.position.y+centerY, GDXRacing.camera.position.z+centerZ, 0, 1, 0);

if(Gdx.input.isKeyPressed(Keys.A))
{
yaw-=2;
}
if(Gdx.input.isKeyPressed(Keys.D))
{
yaw+=2;
}
if(Gdx.input.isKeyPressed(Keys.W))
{
pitch+=2;
}
if(Gdx.input.isKeyPressed(Keys.S))
{
pitch-=2;
}
if(Gdx.input.isKeyPressed(Keys.R))
{
yaw = 0;
pitch = 0;
}

if(pitch>89)
{
pitch = 89;
}else if(pitch<-89){
pitch = -89;
}
}
``````

There are probably many things that could be improved with this code, but it worked for me so I will leave it. If you stumble upon this in the future, there you go :)

-