tags:

views:

311

answers:

4

So I have a function in an app that needs to let the user calculate a trig function (sin,cos,tan) using radians OR degrees, and also to expect a returned value from inverse trig functions (asin,acos,atan) as either radians or degrees. is there any way to do this without building in a converter directly into the way they input something? what i am trying to avoid is having to convert: sin(45) to sin(dtor(45)) thanks!

A: 

There isn't a way to change the way the functions operate.

A "solution" would be to re-make the interface, and do the conversions:

// for example
float sin(float pX)
{
    return std::sinf(d2r(pX));
}

And use that interface instead. Put it in a math:: namespace.

GMan
alright, i see how i wanna do this now, thanks
Sj
You really shouldn't use degrees as the internal representation of angles, see http://en.wikipedia.org/wiki/Radian#Advantages_of_measuring_in_radians
Andreas Brinck
oh i definitely agree. i hate degrees and prefer radians by far. its more of it being a UI element, 90% of users arent going to be familiar with radians, theyll prefer degrees so i plan on accomadating it
Sj
+2  A: 

This should really be handled by the display / input routines in your app. Have a switchable mode to use either degrees or radians, and your IO routines either do the conversion or not depending on the mode. I mean, 90 degrees is pi/4 radians, just displayed using a dumb convention -- since they represent the same quantity, there shouldn't be any difference in how they are handled computationally, just a quirk of representation akin to localization.

Your actual calculation code then only has to support one mode (which should be radians).

Stephen Canon
the only issue with it is that with large equations it starts hanging up a bit and i am trying to avoid it
Sj
Whether the conversion happens in your IO routines or in the computational engine, it's only a single multiply either way. If it's having an appreciable performance impact, something else is amiss.
Stephen Canon
A: 

Not sure there's any real way around it if you can accept both degrees and radians. There's no way to tell just from the input which units you're using. For example, sin(2) has a valid value for 2 degrees and 2 radians.

You have to do the appropriate conversion before inputting to the functions. (Or, you have to convert the output of the inverse trig functions if they want degrees.)

John at CashCommons
A: 

I suggest using a modification of GMan's solution, and create a class containing member functions that are trig function wrappers, and which operate in degrees of radians depending on a mode variable.

class cTrig
{
    enum eTrigMode
    {
        DEGREES,
        RADIANS
    }

    cTrig( eTrigMode mode = DEGREES ) : m_mode(mode) {}

    void setMode( eTrigMode mode ) { m_mode = mode }


    double sin( double theta )
    {
        return std::sin( m_mode == DEGREES ? deg_to_rad(theta) : theta ) ;
    }

    // ... etc for all other trig functions
} ;

That way you can create either two cTrig objects with different modes, or one object and change mode as necessary. I'd go for the former:

cTrig degrees( cTrig::DEGREES ) ;
cTrig radians( cTrig::RADIANS ) ;

double a = degrees.sin( 90 ) ;
double b = ragians.sin( M_PI ) ;

I'd also include deg_to_rad and rad_to_deg as member functions of cTrig.

You could alternatively create cRadian and cDegree types and overload the functions for those types.

Clifford