21 replies to this topic

Posted 31 October 2012 - 04:45 PM

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!

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!

Posted 31 October 2012 - 04:54 PM

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.

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

Posted 31 October 2012 - 04:56 PM

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]

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, 31 October 2012 - 04:56 PM.**

Posted 31 October 2012 - 05:07 PM

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.

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);

glRotatef(headingDegrees, 0, 1, 0);

Posted 31 October 2012 - 05:21 PM

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.

Posted 31 October 2012 - 05:22 PM

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?

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?

Posted 31 October 2012 - 05:36 PM

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.

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.

Posted 31 October 2012 - 06:08 PM

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.

Posted 01 November 2012 - 02:26 AM

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.

Sorry for all these questions, it's just that I'm very bad at math and all these terms and notions puzzle me.

Posted 01 November 2012 - 02:33 AM

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(**rotationAngle**, CP.x, CP.y, CP.z); // where **CP** 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**rotationAngle** and the **CP** vector. Also this is something that I can't figure if and how is possible.

So I can't do something like this:

glRotatef(

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

Posted 01 November 2012 - 03:01 AM

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?

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?

Posted 01 November 2012 - 03:13 AM

Well, changing SDK unfortunately is not an option

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.

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.

Posted 01 November 2012 - 05:06 AM

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 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.

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.

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.Well, changing SDK unfortunately is not an option

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.

I'll see if I can demonstrate the issue with a very simple experiment for you.

- 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.
- Tilt your head towards the left instead.

That is the difference between direction and orientation: you have a direction and you want an orientation.

**Edited by Brother Bob, 01 November 2012 - 05:07 AM.**

Posted 01 November 2012 - 06:09 AM

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

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)"...

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

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, 01 November 2012 - 06:17 AM.**

Posted 01 November 2012 - 06:23 AM

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.

Posted 01 November 2012 - 07:32 AM

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) 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.

Posted 01 November 2012 - 09:10 AM

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"

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"

Posted 01 November 2012 - 01:43 PM

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

Posted 02 November 2012 - 01:00 AM

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.