template<class T>
Magnum::Math::Deg class

Angle in degrees.

Along with Rad provides convenience classes to make angle specification and conversion less error-prone.


You can enter the value either by using a literal:

using namespace Literals;

auto degrees = 60.0_degf;       // type is Deg<Float>
auto radians = 1.047_rad;       // type is Rad<Double>

Or explicitly convert a unitless value (such as output from some function) to either degrees or radians:

Double foo();

Deg<Float> degrees(35.0f);
Rad<Double> radians(foo());
//degrees = 60.0f;              // error, no implicit conversion

The classes support all arithmetic operations, such as addition, subtraction or multiplication/division by a unitless number:

auto a = 60.0_degf + 17.35_degf;
auto b = -a + 23.0_degf*4;
//auto c = 60.0_degf*45.0_degf; // error, undefined resulting unit

It is also possible to compare angles with all comparison operators, but comparison of degrees and radians is not possible without explicit conversion to common type:

Rad<Float> angle();

Deg<Float> x = angle();         // convert to degrees for easier comparison
if(x < 30.0_degf) foo();
//if(x > 1.57_radf) bar();      // error, both need to be of the same type

It is possible to seamlessly convert between degrees and radians and explicitly convert the value back to the underlying type:

Float sine(Rad<Float> angle);
Float a = sine(60.0_degf);      // the same as sine(1.047_radf)
Deg<Double> b = 1.047_rad;      // the same as 60.0_deg
Float d = Double(b);            // 60.0
//Float e = b;                  // error, no implicit conversion

Requirement of explicit conversion

The requirement of explicit conversions from and to unitless types helps to reduce unit-based errors. Consider following example with implicit conversions allowed:

namespace std { float sin(float angle); }
Float sine(Rad<Float> angle);

Float a = 60.0f;                // degrees
sine(a);                        // silent error, sine() expected radians

auto b = 60.0_degf;             // degrees
std::sin(b);                    // silent error, std::sin() expected radians

These silent errors are easily avoided by requiring explicit conversions:

//sine(a);                      // compilation error
sine(Deg<Float>{a});            // explicitly specifying unit

//std::sin(b);                  // compilation error
std::sin(Float(Rad<Float>(b));  // required explicit conversion hints to user
                                // that this case needs special attention
                                // (i.e., conversion to radians)

Base classes

template<template<class> class Derived, class T>
class Unit
Base class for units.

Constructors, destructors, conversion operators

Deg(ZeroInitT = ZeroInit) constexpr noexcept
Construct zero angle.
Deg(NoInitT) explicit noexcept
Construct without initializing the contents.
Deg(T value) explicit constexpr noexcept
Explicit constructor from unitless type.
template<class U>
Deg(Unit<Math::Deg, U> value) explicit constexpr noexcept
Construct from another underlying type.
Deg(Unit<Math::Deg, T> other) constexpr noexcept
Copy constructor.
Deg(Unit<Rad, T> value) constexpr
Construct degrees from radians.

Function documentation

template<class T>
Magnum::Math::Deg<T>::Deg(Unit<Rad, T> value) constexpr

Construct degrees from radians.

Performs conversion from radians to degrees, i.e.:

LaTeX Math \[ deg = 180 \frac {rad} \pi \]

template<class T>
Deg<Double> operator""_deg(long double value) constexpr

Double-precision degree value literal.

Example usage:

Double cosine = Math::cos(60.0_deg);  // cosine = 0.5
Double cosine = Math::cos(1.047_rad); // cosine = 0.5

template<class T>
Deg<Float> operator""_degf(long double value) constexpr

Single-precision degree value literal.

Example usage:

Float tangent = Math::tan(60.0_degf);  // tangent = 1.732f
Float tangent = Math::tan(1.047_radf); // tangent = 1.732f

template<class T> template<class T>
Corrade::Utility::Debug& operator<<(Corrade::Utility::Debug& debug, const Unit<Deg, T>& value)

Debug output operator.