Wierd problem with sin/cos.
Sebastian Mineur

Hey, guys!
I just recently started working on a project involving a lot of angles and vector math, but I seem to have hit a pretty nasty bump in the road...

It has to do with the standard 'sin' and 'cos' functions in 'math.h', and that they sometimes return really funky values.

Look here, this is a short program I've put together that reproduces the funkiness:

1#include <iostream>
2#include <math.h>
3 
4using namespace std;
5 
6int main() {
7 const float PI = 3.14159265f;
8 
9 cout << "acos(1.0) = " << acos(1.0f) << "\n";
10 cout << "acos(0.0) = " << acos(0.0f) << "\n";
11 cout << "acos(-1.0) = " << acos(-1.0f) << "\n";
12 cout << "\n";
13 cout << "cos(0.0) = " << cos(0.0f) << "\n";
14 cout << "cos(PI) = " << cos(PI) << "\n";
15 cout << "cos(-PI) = " << cos(-PI) << "\n";
16 cout << "cos(PI/2) = " << cos(PI/2.0f) << "\n";
17 cout << "cos(-PI/2) = " << cos(-PI/2.0f) << "\n";
18 cout << "\n";
19 cout << "sin(0.0) = " << sin(0.0f) << "\n";
20 cout << "sin(PI) = " << sin(PI) << "\n";
21 cout << "sin(-PI) = " << sin(-PI) << "\n";
22 cout << "sin(PI/2) = " << sin(PI/2.0f) << "\n";
23 cout << "sin(-PI/2) = " << sin(-PI/2.0f) << "\n";
24 cout << "\n";
25 
26 system("PAUSE");
27 return EXIT_SUCCESS;
28}

And when compiled, on my machine, it gives:

Quote:

acos(1.0) = 0
acos(0.0) = 1.5708
acos(-1.0) = 3.14159

cos(0.0) = 1
cos(PI) = -1
cos(-PI) = -1
cos(PI/2) = -4.37114e-08
cos(-PI/2) = -4.37114e-08

sin(0.0) = 0
sin(PI) = -8.74228e-08
sin(-PI) = 8.74228e-08
sin(PI/2) = 1
sin(-PI/2) = -1

You can see here that 'acos' works perfectly, but some of the return values from 'sin' and 'cos' look, outright, wrong!
More specifically, cos(PI/2) and cos(-PI/2) should return 0.0, right? And cos(-PI) should return positive 1.0, not negative.
Same thing with 'sin', 'cause sin(PI) and sin(-PI) should also return 0.0, shouldn't they?

Hmmm... I just now realised that even THAT's not right, because typically 0.0 degrees is straight to the right, and 'cos' gives the y-axis and 'sin' the x-axis. If I'm not mistaken.

Oh, well. I'm at a loss, here. Any help is greatly appreciated!

kdevil

The outputs look fine to me, but you have it backwards: cos gives the x-axis and sin gives the y axis.

cos(PI/2) and sin(PI) should return 0, but there's probably some inaccuracy due to floats not being able to exactly represent pi/2 (and also because your PI is just 9 digits long - try it again using Allegro's AL_PI or M_PI from math.h). So, because of that, you get something very close to 0, but not quite.

Sebastian Mineur

Ah, thanks.
I get the same results with M_PI, but what you're saying then is basically that -4.37114e-08 is actually just a really low number, like -0.0000000437... or something?

Goalie Ca

Remember that <math>\pi = -\pi + 2\pi</math>

And those other non-zero but approximately zero numbers are sadly just rounding errors. Software probably uses a modified taylor series to calculate it but obviously it doesn't calculate all infinite terms.

Johan Halmén

acos(-1.0) = 3.14159

...is more off the right value than...

cos(PI/2) = -4.37114e-08

Sebastian Mineur

Mmm, then it was all just a matter of inaccuracy. It should still be accurate enough though, for the purposes of my project.

Goalie Ca said:

Remember that pi = -pi + 2pi

Yes, it looks obvious enough, but I guess I actually didn't really think about that. I'm not used to working with radians, and I was still thinking of it like degrees. Starting at 0 and going around clockwise to 360.
But, radians then, start at pi going counter-clockwise, full circle, to -pi.

That IS an important thing to remember.

Thanks for the help :)

EDIT:
Or... Maybe it's not counter-clockwise, I don't know. My point is that to make a full circle with radians, you would start at PI, straight to the left, go around to 0, straight to the right, and then on to -PI.

Goalie Ca

I think you should look at this
http://en.wikipedia.org/wiki/Unit_circle

Matt Smith

..but bear in mind that mathematicians have y going up the page, while us computer people have it going down the screen.

Arthur Kalliokoski
Quote:

mathematicians have y going up the page, while us computer people have it going down the screen.

To clarify, programmers were used to starting text at the upper right corner of the screen (as is normal) and continuing across, then going to the next line down. When they started fiddling with bitmap graphics, they continued the practice because they were used to it. Mathmaticians usually refer to the 1st quadrant as it has x and y positive, so y=0 is at the bottom.

[EDIT] As pointed out below, start at upper left Doh!

Ron Novy
Quote:

To clarify, programmers were used to starting text at the upper right corner of the screen (as is normal) and continuing across, then going to the next line down. When they started fiddling with bitmap graphics, they continued the practice because they were used to it. Mathmaticians usually refer to the 1st quadrant as it has x and y positive, so y=0 is at the bottom.

Isn't that the upper left corner? ::)

Karadoc ~~
Quote:

Ah, thanks.
I get the same results with M_PI, but what you're saying then is basically that -4.37114e-08 is actually just a really low number, like -0.0000000437... or something?

Yes. That's exactly what -4.37114e-08 is. The "e-08" notation thing at the end means "times ten to the power of negative 8. So it is exactly what you said.

Matt Smith

-4.37114×10⁻⁸

Unicode FTW ✌☺✌

Slartibartfast
Quote:

My point is that to make a full circle with radians, you would start at PI, straight to the left, go around to 0, straight to the right, and then on to -PI.

1) When using radians, x = x + 2*Pi*k. So -Pi is equal to Pi which is equal to 3*Pi.
2) You can start wherever the hell you like (remember, a circle has no start nor an end), however for mathematical reasons it is usually more comfortable to use the range [-Pi,Pi].
3) The way you describe this doesn't make sense to me.

Thread #596119. Printed from Allegro.cc