Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


Calculating angles of rotation


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
21 replies to this topic

#1 Alessandro   Members   -  Reputation: 296

Like
0Likes
Like

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!

Posted Image

Sponsor:

#2 Brother Bob   Moderators   -  Reputation: 8453

Like
1Likes
Like

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.

#3 luca-deltodesco   Members   -  Reputation: 637

Like
1Likes
Like

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]

Edited by luca-deltodesco, 31 October 2012 - 04:56 PM.


#4 Alessandro   Members   -  Reputation: 296

Like
0Likes
Like

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

#5 Brother Bob   Moderators   -  Reputation: 8453

Like
1Likes
Like

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.

#6 Alessandro   Members   -  Reputation: 296

Like
0Likes
Like

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?

#7 Brother Bob   Moderators   -  Reputation: 8453

Like
1Likes
Like

Posted 31 October 2012 - 05:24 PM

That's spot on.

#8 Alessandro   Members   -  Reputation: 296

Like
0Likes
Like

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.

Posted Image

Posted Image

#9 Brother Bob   Moderators   -  Reputation: 8453

Like
1Likes
Like

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.

#10 Alessandro   Members   -  Reputation: 296

Like
0Likes
Like

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.

#11 Alessandro   Members   -  Reputation: 296

Like
0Likes
Like

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.

#12 luca-deltodesco   Members   -  Reputation: 637

Like
1Likes
Like

Posted 01 November 2012 - 03:01 AM

Use a better SDK? :P

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?

#13 Alessandro   Members   -  Reputation: 296

Like
0Likes
Like

Posted 01 November 2012 - 03:13 AM

Well, changing SDK unfortunately is not an option Posted Image

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.

#14 Brother Bob   Moderators   -  Reputation: 8453

Like
1Likes
Like

Posted 01 November 2012 - 05:06 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.

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.

Well, changing SDK unfortunately is not an option Posted Image

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.

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.
  • 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.
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, 01 November 2012 - 05:07 AM.


#15 Alessandro   Members   -  Reputation: 296

Like
0Likes
Like

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 Posted Image

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.


#16 Brother Bob   Moderators   -  Reputation: 8453

Like
1Likes
Like

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.

#17 taz0010   Members   -  Reputation: 275

Like
1Likes
Like

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.

#18 Olof Hedman   Crossbones+   -  Reputation: 2908

Like
1Likes
Like

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"

#19 luca-deltodesco   Members   -  Reputation: 637

Like
1Likes
Like

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.

#20 Alessandro   Members   -  Reputation: 296

Like
0Likes
Like

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.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS