Jump to content

how to take the short rotation direction


Recommended Posts

Hi all,


I'm importing my camera position and rotation from a .max export to .Babylon. And I make the camera fly from 1 camera point to the other.

But in some cases the camera rotation rotates like 270 degrees to get to the end rotation. I've set up the angles in this playground.




How can I calculate the difference in angle between 2 vectors and convert 1 of them to make sure that the shortest route will be taken?




To clarify:


Link to comment
Share on other sites

You can use the Dot Product to find the shortest angle between the vectors. Let A be the vector defined by the dark blue colored arrow and let B be the vector defined by the cyan colored arrow. 


The Dot Product of two vectors can be calculated using any of two equations.

One equation states that the Dot Product of 2 vectors is the product of the magnitude of the vectors times the cosine of the shortest angle (theta) between them, written as:

A . B = ||A|| ||B|| cos(theta)


The other equation finds the dot product by taking the product of the x and y components of the two vectors and adding them together, written as:
A . B = AxBx + AyBy


These equations are equivalent so you can solve for theta using:
AxBx + AyBy = ||A|| ||B|| cos(theta)


However you can simplify things a great deal by normalizing the two vectors so that their magnitudes are of unit length. Once normalized the magnitudes of A and B are both 1. So you end up with.
An = normalize( A )

Bn = normalize( B )

And from that you get:
AnxBnx + AnyBny = cos(theta) 

and theta can be found using:
theta = arccos(AnxBnx + AnyBny)

There is still one problem though. Theta is just the raw angle of rotation, a scalar value. It doesn't tell you whether you should be doing clockwise rotation or counter-clockwise rotation from A to B. To figure that out you'll have to use the 2D version of the Cross-Product (aka Wedge Product).

To find the 2D Cross-Product of vector A and B use the following equation:
A X B = AxBy - AyBx


Now what you want to know is if the result of the above gives you a +ve or -ve value. If +ve you have clockwise rotation, if -ve you have counter-clockwise rotation. Once you know that you can make theta -ve or leave it as +ve.

Link to comment
Share on other sites

I assumed this was a 2D question. These concepts can be applied to 3D (Babylon's Vector3 class has the requisite methods to cover both dot and cross products), but you'd be far better off using quaternions (Babylon's Quaternion class should cover your needs).


If you go the Quaternion route you'll still need to find the angle using the dot product. You'll need the cross produlct as well, but to determine the axis of rotation. In 3D the cross-product of 2 vectors gives you a vector that is perpendicular to both vector (which can then serve as the axis of rotation common to both). You can use the Vector3's cross product method to calculate that vector and then pass that vector and the angle to the method Quaternion::RotationAxis(angle, axis) to get the Quaternion. Then you can use the slerp method on it to smoothly animate the camera.


Best part is that you don't have to worry about clockwise and counter-clockwise rotation (as in the 2D case). That comes built in once your calculate the axis of rotation.

Link to comment
Share on other sites

Hi Adam,

thanks for your reply. And clever to use the box for the rotationQuaternion.

The rotation seems to be taking the short route. But the starting and ending viewpoint is different from my example.

I noticed that you had shifted the value's in the fromRotation and toRotation.

But changing it to my original value's unfortunately didn't fix it.(though hard to see.. with only clouds ;-)


I'll try to do what Dimumurray suggested with your method.

Link to comment
Share on other sites

I don't have any implementation for you but here's a decent series of videos that cover the theory behind how Quaternions work. 


Math For Game Developers - Quaternions

Once you get that under you belt you should be able to look at the Babylon.js APIs and figure out how best to solve the problem. Better yet you'll have a solid grasp of quaternions and when to apply them.  

Link to comment
Share on other sites

It does look like there is an issue with my proposed solution.


I can't make the camera ease to the left using a negative value:





I'm no quaternion expert but it looks to me like Babylon's quaternion.toEulerAngles() is buggy:

BABYLON.Quaternion.RotationYawPitchRoll( 0, 0.1, 0 ).toEulerAngles()t {x: 0, y: 0.09999999999999945, z: 0}BABYLON.Quaternion.RotationYawPitchRoll( 0, -0.1, 0 ).toEulerAngles()t {x: 3.141592653589793, y: 0.09999999999999945, z: -3.141592653589793}

For your demo, if you avoid conversions by parenting the camera to the mesh with the rotation quaternion, it should work:


Link to comment
Share on other sites

well.. it seems my problem was easy to fix.. I feel a bit stupid.

I just checked for every axis:

if (Math.abs(fromRotation.x-toRotation.x)> Math.PI) {
        if ((fromRotation.x-toRotation.x)>0) {
            fromRotation.x = fromRotation.x-Math.PI*2;
        } else {
            fromRotation.x = fromRotation.x+Math.PI*2;


But finding out about the math for game developers is very nice.

Thanks for all your replies!

Link to comment
Share on other sites

  • 2 years later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...