Followers 0

# Calculating angles of rotation

## 21 posts in this topic

Given a XYZ coordinate system, and a vector AB as represented in the attached image (where A is matching the world center 0,0,0 ), how could I calculate the angles of rotation of AB along the 3 axis?
Meaning that if you start with AB at 0,1,0 I'd like to know what angle rotations have been applied to achieve its new position (which is known) in space.
To put it into numbers, if AB is at (0,1,0) and later you set it at (1,0.4,0.3), there is a way to calculate the angles that if forms within the x,y,z axis?

I don't know if the image are really explanatory, let me know if you need further info. Thanks for any help!

[img]http://www.alessandromastronardi.com/axistest.jpg[/img]
0

##### Share on other sites
First calculate the cross-product between the original vector and the vector AB: that will give you an axis of rotation. Then calculate the dot-product between the original vector and the vector AB: that will give you the arccosine of the angle between them and consequently the angle to rotate.

That will give you the smallest possible rotation in order to rotate a vector from some original direction to the direction AB.
1

##### Share on other sites
You only need 2 angles to specify a direction in 3 dimensions, and your question really depends on what axis those rotations should be about, and in what order the rotations are supposed to occur.

Even specified properly, there's no total solution, since you can end up with gimbal lock, eg:

Say you define the rotations to be: a rotation about the y-axis, then a rotation about the x-axis; if AB starts at (0, 1, 0) then it is only possible to define the rotations if the new AB happens to be in the yz plane. No matter how you specify the two rotations you will end up with this problem. I 'guess' you could add a third rotation, that is only used in this corner case; but really you can probably do much better with a different representation of rotation, whether it be a quaternion or axis-angle

[Edit: Bob's suggestion is to use axis-angle] Edited by luca-deltodesco
1

##### Share on other sites
[quote name='Brother Bob' timestamp='1351724043' post='4995977']
First calculate the cross-product between the original vector and the vector AB: that will give you an axis of rotation. Then calculate the dot-product between the original vector and the vector AB: that will give you the arccosine of the angle between them and consequently the angle to rotate.

That will give you the smallest possible rotation in order to rotate a vector from some original direction to the direction AB.
[/quote]

Thanks Bob, but in a opengl context, if I gather "the arccosine of the angle between them and consequently the angle to rotate.", how would I use such angle on individual axis?
I mean, what if I need to use some commands like:

glRotatef(bankDegrees, 0, 0, 1);
glRotatef(pitchDegrees,1, 0, 0);
0

##### Share on other sites
It is not a well defined problem in that situation. As Luca said, you only need two of the three angles in that case. The third one is arbitrary. The problem is that a vector or a direction is not an orientation, and rotations deal with orientations.
1

##### Share on other sites
Reading back what Bob wrote, probably I should to something like this:

vector CP = cross product between the original vector and the vector AB
rotationAngle = arccosine(dot-product between the original vector and the vector AB)

Now I could do something like this:

glRotatef(rotationAngle, CP.x, CP.y, CP.z);

Am I on the right path?
0

That's spot on.
1

##### Share on other sites
Just to give more details, here is what i'm trying to do. In the first image, I have a guide line, made of two points (whose coordinates are known), and I need to replace that guide with a 3D object (see second image).

Placing the 3D object it's simple, since I already know the guide base point coordinates, but I'd like to orient the 3D object so that it matches the guide orientation as well. And the issue I have is to calculate those angles so that I can apply those to the 3D object as well.

[img]http://www.alessandromastronardi.com/img1.jpg[/img]

[img]http://www.alessandromastronardi.com/img2.jpg[/img]
0

##### Share on other sites
Looks like your guide is a direction and not an orientation, and, as I said, rotations deal with orientations and not with directions. In order to orient the object in the direction of the guide, you need additional information or constraints to disambiguate how the direction maps to an orientation. For example, the constraint in my first reply was that it was the minimum possible rotation, and that solution is unique in most cases. Just saying that you want the object to be rotated in a specific direction just isn't enough information to construct a rotation.
1

##### Share on other sites
I think I understand what you mean, but then, I'd possibly solve this matter? Would the solution you provided in your first reply do it ? BTW, what means the "constraint was that it was the minimum possible rotation"?
Sorry for all these questions, it's just that I'm very bad at math and all these terms and notions puzzle me.
0

##### Share on other sites
I also would like to ask this. Since the application I'm working on is based on a SDK and does not accept direct opengl commands, I need to apply rotation angles separately.

So I can't do something like this:

glRotatef([b]rotationAngle[/b], CP.x, CP.y, CP.z); // where [b]CP[/b] is a vector representing the axis of rotation

but I rather have to:

setRotX(angleX);
setRotY(angleY);
setRotZ(angleZ);

I need, to provide the three angle components (that the right term) for each axis, obviously gathered from the [b]rotationAngle[/b] and the [b]CP[/b] vector. Also this is something that I can't figure if and how is possible.
0

##### Share on other sites
Use a better SDK?

We need to know what order the final transform gets applied, does it do X followed by Y, followed by Z or some other order?
1

##### Share on other sites
Well, changing SDK unfortunately is not an option [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]

The order of rotation is ZXY.

I'm so bad at math that I'm really amazed to realize how something that I figured out a simple operation (place an object at the same base point of a guide, and orient it along it), instead seems to be so complicated.
I hope you guys can come up with a solution to help me with this.
0

##### Share on other sites
[quote name='Alessandro' timestamp='1351758378' post='4996109']
I think I understand what you mean, but then, I'd possibly solve this matter? Would the solution you provided in your first reply do it ? BTW, what means the "constraint was that it was the minimum possible rotation"?
Sorry for all these questions, it's just that I'm very bad at math and all these terms and notions puzzle me.
[/quote]
My solution is one way of doing it given the constraint I assumed. As has been said, you need to fix the problem that your direction vector does not correspond to an orientation. There are infinitely many orientations, and consequently infinitely many rotations that you can apply, that maps your original vector to the vector AB. You need additional information to reduce this set from infinity to one.

I just claim that I want the shortest possible rotation. The solution I proposed gives you the shortest possible rotation. There is no other rotation that has a shorter angle.
The final orientation may not be what you expect, but the object is indeed pointing in the right direction just as you requested.
[quote name='Alessandro' timestamp='1351761187' post='4996121']
Well, changing SDK unfortunately is not an option [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]

The order of rotation is ZXY.

I'm so bad at math that I'm really amazed to realize how something that I figured out a simple operation (place an object at the same base point of a guide, and orient it along it), instead seems to be so complicated.
I hope you guys can come up with a solution to help me with this.
[/quote]
As has been said also, you only need two rotations but an ZXY order has three rotations. One rotation must be removed from the calculation or you have too many rotations to solve the problem. You could, for example, leave one of the rotations at zero degrees and calculate the other two. That will give you a unique solution. But the problem is that you have three angles and thus three ways to zero an angle, leaving you with three different solutions. Three different solutions that indeed give you three different orientations.

I'll see if I can demonstrate the issue with a very simple experiment for you.[list=1]
[*]Sit in front of your computer as usual, looking towards your screen. Your face is now facing the direction towards the screen.
[*]Tilt your head towards the right but keep looking at the screen. Your face is still facing the direction towards the screen, but the head is tilted 20-ish degrees.
[/list]
In all three points, your head is facing towards your screen. Thus, they all satisfy your wish to face in a certain direction, but their orientations are different, since you tilt your head to the sides.

That is the difference between direction and orientation: you have a direction and you want an orientation. Edited by Brother Bob
1

##### Share on other sites
I think I understand what you mean. Sorry to be so stubborn but, in my case, the guide represent both the direction and the orientation, wouldn't it?
I mean, I just need to orient and direct a 3d object so that it matches that guide.
You're all allowed to insult me if I still can't understand it [img]http://public.gamedev.net//public/style_emoticons/default/biggrin.png[/img]

I mean, if that guide has origin at (0,0,0), and aims at (0,1,1), there must be a chance to say "Ok, let get another object, sets its origin at (0,0,0) as well, and aim it at (0,1,1)"... Edited by Alessandro
0

##### Share on other sites
No, your direction is still only a direction. Once the object is facing the guide-vector, you can rotate is arbitrarily around the guide-axis and it will still face the guide-vector. You can face an object towards the X-axis if you like, but you can rotate is as much as you like around the X-axis and it will still face towards X-axis. You need something else to fix the orientation because the direction isn't enough.
1

##### Share on other sites
I'd do it like this:

1) Project the destination vector onto the XZ axis. Do this simply by setting the y component to zero. The projected vector will no longer be normalised.
2) Get the angle between the object's vector and the vector resulting from 1), and rotate around the y axis by this amount.
3) Now you can rotate your object onto the destination vector using the method outlined earlier in this thread (cross product vectors to get rotation axis, dot product to find angle). This will cause the object to point at the destination vector without any undesired rotation along the object's local x axis.
1

##### Share on other sites
It's the same problem as when you are placing a camera.

besides having the direction the camera should look, you also need the up-vector to... know which direction is up.

If you don't care, just set the up vector to Vec3(0,1,0) or something. (preferably the same axis as your local up is)
Personally, I would construct the orientation matrix from the direction and up-vector, something like this (use the syntax from our own vector lib, but I think its self explanatory):

Vec3 right = dir.cross(up);
Vec3 newup = right.cross(up);
Mat4 m(dir.normalize(), newup.normalize(), right.normalize()); //Sets columns to the vectors, assuming local x is "forward", and z is "right" and y is "up"
1

##### Share on other sites
Previous two responses: I think you missed his response that the API he's using permits ONLY setting z-x-y euler angles.
1

##### Share on other sites
Just to report that thanks to all your suggestions I managed to solve this matter. As you wrote I calculated the rotation axis and the angle between the guide and the object, rotated the object, built up a quaternion from it and extracted the euler angles.
0

##### Share on other sites
There seems to be a general lack of trig know-how on this thread..
I wrote this function for an aimbot known as 'ViperG' in a file that's dated june 24th, 2001
I've commented it and adjusted it a bit. You might need to swap some things, but this should help you understand the jist of what you're trying to accomplish..

[source lang="cpp"]

void VectorAngles( float *vector, float *angles )
{
float tmp, yaw, pitch;

if (!vector[0] && !vector[1]) // no horizontal length
{
if (vector[2] > 0) // straight up
pitch = 90;
else
pitch = -90; // straight down

yaw = 0; // can't discern a heading with xy of zero
}
else
{
yaw = (atan2(vector[1], vector[0]) * RAD2DEG);

if (yaw < 0) // set yaw between 0-360
yaw += 360;

// get horizontal length of vector
tmp = sqrt (vector[0]*vector[0] + vector[1]*vector[1]);

// use horizontal length and vector[z] to get pitch
pitch = (atan2(vector[2], tmp) * RAD2DEG);
}

angles[0] = pitch;
angles[1] = yaw;
angles[2] = 0;
}

[/source]

To use this function you'd do

[source lang="cpp"]
...

float vector[3], angles[3];

VectorAngles(vector, angles);

// angles now contains yaw/pitch euler interpretation of vector..

...

[/source]
Let me know if you have any further questions..
0

##### Share on other sites
Thanks a lot, I'm going to try this as well!
0

## Create an account

Register a new account