template<class T>
Deg class
Angle in degrees.
Contents
Along with Rad provides convenience classes to make angle specification and conversion less error-prone.
Usage
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>
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.