Skip to content

Radians and Degrees

Tony Van Eerd edited this page Dec 4, 2019 · 2 revisions

Source: Radians.h

Radians and Degrees are two types (built from Unit) used to avoid errors of mixing up radians and degrees when passed around as floats.

Radians and Degrees are interchangeable, and do the proper math on conversion. (There is, of course, a small cost to that math, so don't convert on every pixel or something like that. (Actually, even then, you are probably still waiting for the memory bus to give you the next pixel...))

void setLaunchAngle(Radians angle);
Radians calcLaunchAngle();

void f()
{
    // we want to work in Degrees,
    // and don't care what calcLaunchAngle and setLaunchAngle work with
    Degrees angle = calcLaunchAngle();
    if (closeTo(angle, 90))
        ask("Almost straight up; what goes up must come down. Are you sure?");
    setLaunchAngle(angle);
}

Sometimes you want to get the underlying double value. Since these are based on Unit, you can just call get(). However, that still leaves code vulnerable to errors in refactoring:

std::cout << "angle: " << angle.get(); // is that in radians or degrees???

Did that output degrees or radians? You need to know the type of angle to be sure. And if someone decides to switch angle from Degrees to Radians (for example), will that line of code get missed?

Better:

std::cout << "angle: " << angle.degrees();  // I don't know what angle is, but users like degrees

The member functions .radians() and .degrees() exist on both of Radians and Degrees. So it doesn't matter whether angle is Radians or Degrees, angle.degrees() always returns what you want.

Also useful:

inline double cos(Radians r) { return std::cos(r.get()); }
inline double sin(Radians r) { return std::sin(r.get()); }
inline double tan(Radians r) { return std::tan(r.get()); }

Note ("of course") that you can also pass Degrees to these functions (because of the implicit conversions).

Degrees d = getAngle();
double c = cos(d); // does the right thing!

And also the inverses:

Degrees d = Degrees::acos(c);

Degrees::acos returns the answer in Degrees, and Radians::acos returns it as Radians. You could of course mix them (although not sure why you would want to)

Degrees d = Radians::acos(c);

If you are into auto (I'm not, I'm OIMA - Only in Moderation auto)

auto r = Radians::acos(c); // r is Radians
Clone this wiki locally