PDA

View Full Version : Cosine (Degrees and Radians)

forrestgrant
Jun 27, 2008, 01:24 PM
Hi there, I have a function in my objective c project that plays with sine and cosine... basically:

float y;
float x;
x = 85.09 //any number really
y = cos(x);

The problem is that by default, xcode (or objective c, im not entirely sure which) uses Radians to graph a cosine wave. But I want my answer to come back in degrees. I know all about how to mathematically convert a radian to a degree and vice versa. But for the purpose of actually graphing something, I would love to actually create a cosine wave in degrees. Any ideas?

lee1210
Jun 27, 2008, 01:40 PM
I don't think this is provided by anything in the C standard library math.h. I don't know about any Cocoa frameworks that provide the functionality you're looking for. It's probably best to just make a function CosDegrees or something similar and use cos from math.h and do the manipulation yourself.

-Lee

kalimba
Jun 27, 2008, 02:21 PM
In the example you posted, it appears that the angle value you're passing is meant to be in degrees. The standard C trig functions accept angle parameters in radians, so all you'd need to do is convert your value in degrees to radians before passing to the cos() [or sin(), or whatever] function.

In the past, I've written my own helper functions (or macros) to do these conversions for me -- RAD2DEG() and DEG2RAD() would be what I recommend.

swiftaw
Jun 27, 2008, 02:24 PM
or, just change the last line to y = cos(2*pi*x/360)

kalimba
Jun 27, 2008, 02:29 PM
or, just change the last line to y = cos(2*pi*x/360)
Additionally, if you're concerned about (partial) optimization, you could rewrite this as:

y = cos( pi * x / 180 );

And it's possible to optimize this even further!

forrestgrant
Jun 27, 2008, 02:58 PM
cool, looks like that worked. I knew how to convert degrees to radians, I did not know doing it inside the function would change the entire wave.

Sayer
Jun 28, 2008, 12:34 PM
cool, looks like that worked. I knew how to convert degrees to radians, I did not know doing it inside the function would change the entire wave.

Uh, cosine and sine are both radians-based so yeah they would be different if you passed in Degrees.

Sander
Jun 28, 2008, 05:39 PM
Additionally, if you're concerned about (partial) optimization, you could rewrite this as:

y = cos( pi * x / 180 );

And it's possible to optimize this even further!

I'm pretty sure these constant expressions are eliminated at compile-time. So always write down stuff you can understand later, when you re-read your own code. Don't pre-calculate 2pi/360 yourself and insert that magic number everywhere.

SPUY767
Aug 18, 2008, 06:51 AM
Additionally, if you're concerned about (partial) optimization, you could rewrite this as:

y = cos( pi * x / 180 );

And it's possible to optimize this even further!

CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;};

That line right after your import statements should register that method which should run as fast as something called from the core foundation library without the overhead of a traditional function call to the class itself.

Sander
Aug 19, 2008, 02:29 AM
CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;};

That line right after your import statements should register that method which should run as fast as something called from the core foundation library without the overhead of a traditional function call to the class itself.

That's hoping it gets inlined, which is not guaranteed. Besides, why use CGFloat instead of plain old float (or better still, double)?

lazydog
Aug 19, 2008, 04:39 AM
Hi
You can define the conversion once using a macro, something like this:-

#define RADIANS( degrees ) ( degrees * M_PI / 180 )
...
...
y = cos( RADIANS(x) ) ;

b e n

JVene
Aug 19, 2008, 01:38 PM
In the early days of PC game programming (middle 80's), we used a trick in assembler that you might consider for specialized situations.

If you need considerable accuracy, this won't work.

For early games, we often simplified angles to 1 degree or .5 degree increments. The sin and cos functions from trig are calculated by a number of means (including, say, polynomial approximations) - but there was a time when most of us used a chart - and that's what was often done in the early games.

For 1 degree increments, we created an array for sine, populated each entry in the array with the value of sine for each degree (or, at twice the size, each half degree) - and simply referenced the entry in the array AS the angle in degrees.

This was usually done for the old 386 (and it's ancestors), which didn't have floating point hardware. It's not as much of a speed enhancement today as it was way back when, and I offer the approach only as a view into how this problem was handled under a specialized circumstance.

However, you should consider if there's a performance issue or not. The division takes some time, and if you are concerned about performance, you may find that the user perspective (of degrees) is a display or presentation only, and make the conversion from radians TO degrees for display and input, because it is more common that supplying the 'native' radians to the sin/cos functions is faster because that's more dense processing.