Jump to content
  • Advertisement
Sign in to follow this  
bitshit

Simplifying rotation calculations

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

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Advertisement
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by pTymN
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.

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 this post


Link to post
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 alpha
fsincos // compute sine and cosine of st=alpha
fstps -28(%ebp) // store sine to sin_alpha
fstps 4(%esp) // store cosine to cos_alpha
*snip*


(comments inserted by me)

Share this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by pTymN
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)

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

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!