Question

I'm trying to move around a cube centered at the origin using gluLookAt instead of performing the R*T transformation directly on the object. At first, I was not sure how to do this problem. Then I realized (after implementing half of a solution in circular coords) that I should try using a spherical coordinate system representation. I was able to write some code to do this, but I (the 'eye' of the camera) spin really quickly around the cube. Also, I notice that I'm moving a bit closer to the cube as well instead of holding a constant radius. When I use the Rotate*Translate method, it spins at a more proper rate with the same distance.

My approach for rotation was to use spherical coordinates, but I'm not sure if this is correct. I calculate the two angles, according to the diagram located on the Wikipedia page. I calculate the magnitude of the current point I'm at (distX, distY, distZ). We are initially in the XY plane looking at the negative Z plane). I'm also given two angles, one to specify the angle of rotation about the x-axis and one for the y-axis. These five values are calculated based on how my mouse clicks are made.

I calculate theta and phi based off of some trig and then finally the new position. These formulae can be found in that link earlier. The last step is to plug it into gluLookAt. Again, upon running this program, I am able to spin around the cube, but it is very fast and translates the camera as well. What am I doing wrong?

My code is listed below in case you want to reference it. The part referencing 'y' and 'up' are my attempts to calculate the rotation about the Z axis. The best way I can describe that rotation that is if you look at an object, imagine yourself the camera, and tilt your head left and right. I did not include it in my call to gluLookAt since I couldn't get that to work either.

EDIT: It now rotates at what appears to be the correct rate, but it does not rotate completely. By this, I mean that upon rotating, the "eye" moves towards the cube with an angle, but then will swivel back away, undoing the rotation. But this loops so the path taken by the eye looks similar to a bent infinity symbol.

void sceneTransformation(){
glLoadIdentity( );
    //Using the R*T approach. Works flawlessly
//glTranslatef(-distX, distY, -distZ);
//glRotatef( anglex, 1.0, 0.0, 0.0 );
//glRotatef( angley, 0.0, 1.0, 0.0 );

GLdouble radx = anglex*PI/180.;
GLdouble rady = angley*PI/180.;

GLdouble l = sqrt(pow(distX, 2) + pow(distY, 2) + pow(distZ, 2));
GLdouble phi = atan(distY/distZ) + radx;
GLdouble theta = acos(distZ/l) + radx;


GLdouble deltaZ = l*sin(theta)*cos(phi);
GLdouble deltaY = l*sin(theta)*sin(phi);
GLdouble deltaX = l*cos(theta);


GLdouble ytheta = atan(distX/distY); 
GLdouble y = sqrt(pow(distX,2) + pow(distY, 2));
GLdouble yangle = PI/2.-ytheta-rady;

GLdouble up_y = y*sin(yangle);
GLdouble up_x = y*cos(yangle);

gluLookAt((distX - deltaX), (distY - deltaY), (distZ - deltaZ), 0, 0, 0, 0,1,0);
}
Was it helpful?

Solution

The math functions like sin(), cos(), and friends expect input in radians, not degrees. It looks like you're assuming degrees, so you're spinning roughly 57.3 times (exactly: 360 / (2 * pi)) faster than intended.

OTHER TIPS

You need to make your movement timebased, this means to multiply the rotation angle with the delta between the beginning last and current frame.

angle += 90 * timeDelta; // Rotate by 90 degree each second

There is a fine solution to your problem. take a bit of investigation, but I think it will meet your needs. Quaternions

Some code for it

Good for transforming vector to rotation and backwards

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top