# Simplifying rotation calculations

This topic is 3454 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi, While starting on coding a small game for the old gameboy I was wondering about something; When doing rotations with an increment b over an angle a I use the following formula's: x = r * cos(a + b) y = r * sin(a + b) Following the common way to do rotations, this can be written as: x' = r * cos(a) * cos(b) - r * sin(a) * sin(b) y' = r * sin(a) * cos(b) + r * cos(a) * sin(b) When you substitute in x = r * cos(a) and y = r * sin(a) you get to the formula's that's presented in most textbooks on computer graphics / game programming: x' = x * cos(b) - y * sin(b) y' = y * sin(b) + y * cos(b) Now you only need the objects x & y coords and an increment in the angle you want to rotate over to get the new coords... But I wonder why its never approached by storing the the current angle a for the object (relative to its world axis) and just calculate: x' = r * cos(a + b) y' = r * sin(a + b) Should save a sin and a cos operation, why isnt this approach used on devices with low computational capacity? Martijn

##### Share on other sites
How are you going to implement a translation, such as moving your spaceship straight ahead? I think you need some extra trigonometric to translate your object in your polar coordinate system ( radius , angle ) instead of the normal Cartesian coordinate system (x , y ).

##### Share on other sites
Method A
x' = r * cos(a + b)
y' = r * sin(a + b)

Method B
x' = x * cos(b) - y * sin(b)
y' = y * sin(b) + y * cos(b)

Quote:
 Should save a sin and a cos operation, why isnt this approach used on devices with low computational capacity?

It doesn't save anything, really. In method A, there is one sine and one cosine. In method B there is also one sine and one cosine; although they are used twice each, they only need to be calculated once. So let's call the methods equal at this point.

Now, method B is dependent only on the increment, and not the original angle. If we were transforming one point, there may not be much of a difference. If we had to transform 100 points, then we would have to calculate 100 sines and 100 cosines using method A, but only 1 sine and 1 cosine with method B.

Also, a million other reasons. :)

##### Share on other sites
I recommend that you use 2d rotation vectors if at all possible. The occasional renormalization is cheaper than many sin/cos calls, and you can use simple dot product to rotate a rotation vector by another one.

##### Share on other sites
Quote:
 Original post by pTymNI recommend that you use 2d rotation vectors if at all possible. The occasional renormalization is cheaper than many sin/cos calls, and you can use simple dot product to rotate a rotation vector by another one.

What is a "2d rotation vector"?

I recommend that you use complex numbers if at all possible. The occasional renormalization is cheaper than many sin/cos calls, and you can multiply complex numbers to rotate a complex number by another one.

##### Share on other sites
Worth to mention is that with -ffast-math and -O1, gcc will combine near calls to sin() and cos() into the FPU instruction fsincos:

#include <iostream>#include <cmath>int main () {    using namespace std;    float alpha;    cin >> alpha;    float sin_alpha = sin (alpha);    float cos_alpha = cos (alpha);    cout << "sin:" << sin_alpha << ", cos:" << cos_alpha << endl;}

(-S produces only the assembly)
g++ main.cc -O1 -ffast-math -S

*snip*flds	-24(%ebp)   // load alphafsincos             // compute sine and cosine of st=alphafstps	-28(%ebp)   // store sine to sin_alphafstps	4(%esp)     // store cosine to cos_alpha*snip*

##### Share on other sites
Thanks for the insights guys, I'll look into 2d vectors / complex numbers for doing my rotations then!

PS: arent these called quaternions?

##### Share on other sites
Say that you have a "rotation vector" r that is (sin(30), cos(30)), that's the equivalent of your rotation angle = 30. If you wanted to rotate it by 10 degrees, you'd take r2 = (sin(10), cos(10)) and do an operation like this:

r' = r.x * r2 + r.y * (-r2.y, r2.x)

Occasionally, you'll need to renormalize r.

You can cache the value of r2 and avoid using sin or cos at all. All the fmod(|r| + 360.0f, 360.0f) wraparound stuff that keeps |r| normalized for scalar rotation values can be avoided. Also, it is trivial to use that kind of rotation vector to accumulate linear velocity.

##### Share on other sites
Quote:
 Thanks for the insights guys, I'll look into 2d vectors / complex numbers for doing my rotations then!PS: arent these called quaternions?

The complex numbers are 2D real vectors (usually written as x + y*i) with a multiplication with properties similar to the real one. With this operation they represent rotations in 2D (*). Quaternions are an extension of complex numbers (they are 4D real vectors) and can be used to represent rotations in 3D.

(*) If you have a complex number p = x + y*i that represent the point you want to rotate and the complex number v = cos(a) + sin(a)*i, the complex number q = p*v = x*cos(a) + x*sin(a)*i + y*cos(a)*i + y*sin(a)*i2 = (x*cos(a) - y*sin(a)) + (x*sin(a) + y*cos(a))*i represent the point rotated by an angle a.

[Edited by - apatriarca on January 6, 2009 12:10:51 PM]

##### Share on other sites
Quote:
 Original post by pTymNSay that you have a "rotation vector" r that is (sin(30), cos(30)), that's the equivalent of your rotation angle = 30. If you wanted to rotate it by 10 degrees, you'd take r2 = (sin(10), cos(10)) and do an operation like this:r' = r.x * r2 + r.y * (-r2.y, r2.x)

Oh, that's what you were talking about. That multiplication is not called the "dot product". What you are doing is basically using complex numbers without calling them that. And you probably reversed the roles of sin and cos...

1. 1
2. 2
3. 3
4. 4
Rutin
17
5. 5

• 12
• 9
• 12
• 37
• 12
• ### Forum Statistics

• Total Topics
631419
• Total Posts
2999983
×