Determine current angle of rotation around vector

Started by
27 comments, last by CaptainRedmuff 13 years, 9 months ago
Hello,

I am creating an OpenGL ES camera for the iPhone and have come across a problem when trying to determine the current angle of rotation around a vector.

The camera itself only stores it's current position vector and the world axis up vector. To orient the camera towards a set location, a vector is passed to the lookAt method I have implemented (OpenGL ES doesn't utilise gluLookAt).

My camera works fine in the regard that I can point it towards any location and it will create the appropriate matrix to pass to glMultMatrix. Now that I have implemented this and all is working well, I am now trying to develop methods to allow the camera to rotate around a specific vector with a set angle along a single axis.

The methods I have outlined so far are: (objective c)

- (void)rotateX:(GLfloat)degrees aroundVector:(Vector3D)vector;
- (void)rotateY:(GLfloat)degrees aroundVector:(Vector3D)vector;
- (void)rotateZ:(GLfloat)degrees aroundVector:(Vector3D)vector;

For the time being, I am mainly interested in rotations around the Y axis to simply rotate in a circular orbit around the origin.

The problem I have come across so far is determining the current angle of rotation between the cameras position and the vector passed to the rotate methods.

If I were to set the angle to 0 degrees, the camera will jump from it's current position to the new position calculated by the method. I'd like to be able to increment/decrement the current angle of rotation to smooth out the rotations rather than having to start from 0 degrees each time which doesn't look very nice at all.

To reiterate:

I'd like to be able to find the current angle of rotation between the camera position and a vector along all three axis, one per method as above. Note that this is not the angle between the two vectors, but the angle or rotation around the lookAt vector itself, ie: an angle, in degrees, around the circumference of a circle/sphere along a single axis.

Is this even possible? Are there better ways of moving the camera position around a point where I can increment the angle in steps without having to start from 0 degrees?

Any help would be most appreciated as this has perplexed me currently and I'm not entirely sure what approach I need to take to move forward (or rotate, as it were =P)

Thanks for reading!
Advertisement
You could take the matrix that describes the camera position and convert back to Euler angles. Google for `rotation matrix to Euler angles' and you should get the formulas you need. However, controlling the rotation with Euler angles has a well-known problem called "Gimbal lock".

What you probably want to do is keep the rotation matrix as the representation of the current state, and apply to it small rotations around x, y or z. This has the problem that the matrix would accumulate rounding errors and eventually it would become apparent that it is no longer a rotation matrix. There are several ways of dealing with this, but a relatively simple one is to use Graham-Schmidt orthonormalization.

Would I be able to avoid gimbal lock via the use of quaternions?

I can understand altering the camera matrix to create the desired effect but what I really want is to rotate the camera position around a point before creating the matrix, if that makes sense.

Say the camera position is at (10, 0, 10) looking towards the origin, I want to rotate the camera position so that it's vector is updated from the rotation around a vector before creating the matrix.
Quote:Original post by CaptainRedmuff
Would I be able to avoid gimbal lock via the use of quaternions?

Gimbal lock is a function of what you use to control the rotation, not how you represent it.

Quote:I can understand altering the camera matrix to create the desired effect but what I really want is to rotate the camera position around a point before creating the matrix, if that makes sense.

Say the camera position is at (10, 0, 10) looking towards the origin, I want to rotate the camera position so that it's vector is updated from the rotation around a vector before creating the matrix.


I don't understand exactly what you are saying, but it sounds like you want to describe the camera position as a composition of a rotation and a "look at" operation. That's all good, but do update the rotation incrementally as I described above, instead of using Euler angles.
Let me try to explain further, I apologise for my lack of technical knowledge in advance ;)

Say we have the following setup:

cameraPosition = Vector3D(0.0, 10.0, 0.0);
cameraLookAt = Vector3D(0.0, 0.0, 0.0);
cameraPivot = Vector3D(0.0, 0.0, 10.0);

Now, I can orient my camera from it's position to point towards the LookAt vector using my lookAt method as mentioned previously.

I want to rotate the camera's position vector around the pivot vector so that the cameraPosition value is updated before the call to the lookAt method.

So if I were to rotate around the Y axis, I could call this method:

[camera rotateY:90.0 aroundVector:cameraPivot];

And my camera vector would now be something like (10.0, 10.0, 0.0)

Now my call to the lookAt method would create the appropriate matrix to orient the camera from it's position to the lookAt vector.

Now if I call the rotate method again with the same values, I would have technically made a 180 degree rotation. What I need to find out is the current angle of rotation around the pivot vector, so I can add the second value of 90 degrees to the previous value.

I think the thing that is causing me the most confusion is how to find the current angle of rotation around the point. Seeing that the camera could be anywhere in the world and the pivot point will change over time, the angle between the two will constantly be changing. All I know is I want to update the camera position (via a rotation) before the call to lookAt which creates the view matrix.
Sorry to double reply/bump my own post, i'm still having trouble with this one.

I've been doodling trying to better understand my problem and was wondering if perhaps I was taking the wrong approach. With all the matrix math i've written for my camera class so far I think I may have lost sight of things.

What I really want to be able to do is plot the points along the circumference of a circle, but rather than setting an angle, origin and radius, work backwards and so that the result is simply an angle of rotation around the origin of the circle.

I'm starting to think that instead of something along the lines of

GLfloat x = (radius * cosf(angleInRadians)) + origin.X;
GLfloat y = (radius * sinf(andgleInRadians)) + origin.Y;

I work backwards to derive the angle which x and y sits at somehow?

I know the vector for the camera position and also the vector for the pivot point too. I can calculate the magnitude of the two vectors for the radius so given all the right parameters it seems like there should be a way to work this out.

How do I substitute these values into the right formula to result in the angle? Would this work for absolute axis rotations in 3d? Any help would be appreciated :)

Thanks for reading!
Sorry to bump this post again but i'm still looking for help if anyone can shed some light on the subject please?

I've had a browse around the interwebs and seem to be along the right tracks using acos() to determine the angle of a point along the circumference of a circle given the x and y coordinate.

I've managed to render the circle i want to rotate around by determining the magnitude of the camera position and the pivot point but am still unable to calculate the angle upon which it sits.

If anyone can point me in the right direction, i'd be most appreciative.

Thanks for reading!
I stopped helping you because I can't understand what you want to do. You want to compute coordinates of points in a circle? What does the camera have to do with that? I am also not sure what you mean by "pivot", and whether the coordinates you have for the pivot are in world space or in some other frame of reference.
Hi Alvaro!

I've been prototyping with php trying to better understand the principle of what I want to achieve.

Check this image I rendered as part of my test:

http://img5.imageshack.us/img5/7696/71937787.png

As you can see, the circle in the center has two points drawn along it's circumference, one being a point at 0 degrees (far right) and the other being the camera position at an unknown angle.

The point on the far left is the camera lookAt position, which the line drawn between the lookAt and camera illustrates the direction the camera is facing.

I know the origin of the circle (pivot point) and the camera position (2nd point along circumference) from which I calculated the radius of the circle to draw it's outline.

All I want to achieve is to find the angle upon which the camera is sitting. Visually, I know that this is roughly 260 degrees but how can I work this out given that all I know is the cameras position and the origin of the circle?

In php, the code to calculate the point along the circumference of a circle is

$point['x'] = $origin['x'] + ($radius * cos($angle));
$point['y'] = $origin['y'] + ($radius * sin($angle));

Surely there must be some way to reverse this calculation to arrive at the angle given a point? IE:

$angle = acos($point['x'] + $point['y']);

I know that's not right, but it illustrates what I want to achieve. Am I along the right lines, or completely missing the point here?
You need atan2:
$angle = atan2($point['y'], $point['x']);


This topic is closed to new replies.

Advertisement