# Thread: trig model FPS angle generation

1. ## trig model FPS angle generation

I have come across a lot of math models lately for 3D camera systems. I am stuck on the easiest, which is so frustrating. Basically to calculate all of the trig functions, one has to know 'the angle'. Or 2. I understand that if the spherical nomenclature is applied to the system, and then translated into cartesian coordinates, this would be explanatory. But I have seen programmers use the cartesian without the spherical system as well.

So, in the trig model, where exactly are the angles coming from that when broken down to the unit circle are used for translation and rotation. Is it a single angle for XZ b/c y = 0? I can figure out the rest of the trig math from here if I can imagine the proper use the angles.

my example with 'w' :

Code :

if (key=='w')  //forwards
{
yrotrad = (pRot->yrot / 180 * 3.141592654f);
xrotrad = (pRot->xrot / 180 * 3.141592654f);
}

Where do the rotation angles come from above, yrotrad, xrotrad etc. Are they more for analysis within unit circle, or do they represent a "heading"?
I think I am overthinking this, but there it is. I think I may be getting these mixed up with vectors.

2. Originally Posted by technologist
Where do the rotation angles come from above, yrotrad, xrotrad etc. Are they more for analysis within unit circle, or do they represent a "heading"?

For the most part, the only trigonometry required for 3D graphics (and related simulation aspects) is conversion between polar and rectangular (Cartesian) coordinates.
Code :
void polar_to_rectangular(float angle, float radius, float& x, float& y)
{
}

void rectangular_to_polar(float x, float y, float &angle, float &radius)
{
angle = atan2(y, x);
radius = sqrt(x*x+y*y); // equivalent to hypot(x, y);
}

Spherical coordinates are just repeated application:
Code :
// +y is forward, +z is up
void spherical_to_rectangular(float heading, float elevation, float radius, float& x, float& y, float &z)
{
float d;
}
If you expand out the polar_to_rectangular() calls, you'll end up with something a lot like your existing code.

3. yrotrad is the heading, xrotrad is the elevation (angle from horizontal). However, the change to xpos/zpos should also be multiplied by cos(xrotrad).
Thanks for the response, it broke loose an avalanche of ideas as I thought it would. I was surprised to learn there were not 1 or 3 unit circles, but (2) for 3 Euler angles. Working out the math from that I had some questions:
0. is the unit vector from the Euler angles the "front" of the camera?
1. which is the simplest way to "display" what's in front of my camera now? double buffering? gluLookAt? Another way?
2. I've noticed that the Euler rotations are also found in rotational matrices. I was able to calculate all of the trig "by hand" without matrices. Doesn't make it the best way though - should I use the rotational matrices? I am eventually going to try Quats.
3. can I derive my own rotational matrices, or this pennywise/poundfoolish.
4. I want to implement a keyboard scheme - I have several prototypes already. What should my strategy be here on forwards/reverse/strafe - in general.

4. Originally Posted by technologist
0. is the unit vector from the Euler angles the "front" of the camera?
In terms of your code, it's the direction you move when you press W. In the more general sense, Euler angles are just a way of representing a rotation (i.e. an orthonormal matrix). What that matrix represents depends upon how its used.

Originally Posted by technologist
1. which is the simplest way to "display" what's in front of my camera now? double buffering? gluLookAt? Another way?
Construct matrices which rotate about the X and Y axes, and multiply them. Once you've done that, you can replace the movement code (the columns of the view matrix are the local X/Y/Z axes).

Originally Posted by technologist
2. I've noticed that the Euler rotations are also found in rotational matrices. I was able to calculate all of the trig "by hand" without matrices. Doesn't make it the best way though - should I use the rotational matrices? I am eventually going to try Quats.
I'd suggest using matrices.

Originally Posted by technologist
3. can I derive my own rotational matrices, or this pennywise/poundfoolish.
I'd suggest using GLM.

Originally Posted by technologist
4. I want to implement a keyboard scheme - I have several prototypes already. What should my strategy be here on forwards/reverse/strafe - in general.
Whatever works. The main thing to bear in mind is that view orientation and motion orientation aren't necessarily the same thing. E.g. if you look up or down, you may still want to rotate about the world's vertical axis rather than the view axes (unless you're piloting a spaceship, where there isn't a global "up" direction).

5. Construct matrices which rotate about the X and Y axes, and multiply them. Once you've done that, you can replace the movement code (the columns of the view matrix are the local X/Y/Z axes).
Can you please expand on that? I think I understand how to make the Euler angle matrices for the angles, but I've lost you in *bold* & view matrix.

Another question:

Code :
roty(int a){
s, c = sincos(a)
return np.matrix([[c,0,s,0],
[0,1,0,0],
[-s,0,c,0],
[0,0,0,1]])
}

I understand the math here. I believe this was written in python, just not c++. How do I write this snippet in c++?

6. Originally Posted by technologist
Can you please expand on that? I think I understand how to make the Euler angle matrices for the angles, but I've lost you in *bold* & view matrix.
Code :
glm::mat4 my = glm::rotate(yrot, 0.0f, 1.0f, 0.0f);
glm::mat4 mx = glm::rotate(xrot, 1.0f, 0.0f, 0.0f);
glm::mat4 m = my * mx;
or:
Code :
glm::mat4 m = glm::mat4(1.0);
glm::rotate(m, yrot, 0.0f, 1.0f, 0.0f);
glm::rotate(m, xrot, 1.0f, 0.0f, 0.0f);

Originally Posted by technologist
I understand the math here. I believe this was written in python, just not c++. How do I write this snippet in c++?
Code :
glm::mat4 roty(float a) {
float s = std::sin(a);
float c = std::cos(a);
return glm::mat4(
c, 0.0f,   -s, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
s, 0.0f,    c, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
}

Note that GLM wants the components in column-major order, while numpy uses row-major order.

Also, in the Python version (assuming that it's my original code), sincos() converts its argument from degrees to radians, so code which uses it will be using angles in degrees (that was for compatibility with the legacy OpenGL functions; trig functions in languages or their libraries invariably use radians).