Browse Source

Math: compiling Angle, Color and Half code snippets.

pull/194/merge
Vladimír Vondruš 8 years ago
parent
commit
673caa23bf
  1. 240
      doc/snippets/MagnumMath.cpp
  2. 63
      src/Magnum/Math/Angle.h
  3. 74
      src/Magnum/Math/Color.h
  4. 16
      src/Magnum/Math/Half.h

240
doc/snippets/MagnumMath.cpp

@ -593,4 +593,244 @@ static_cast<void>(q1);
static_cast<void>(q2);
}
{
/* [Deg-usage] */
using namespace Math::Literals;
auto degrees = 60.0_degf; // type is Deg<Float>
auto radians = 1.047_rad; // type is Rad<Double>
/* [Deg-usage] */
static_cast<void>(degrees);
static_cast<void>(radians);
}
{
/* [Deg-usage-convert] */
Double foo();
Deg degrees{35.0f};
Radd radians{foo()};
//degrees = 60.0f; // error, no implicit conversion
/* [Deg-usage-convert] */
static_cast<void>(degrees);
static_cast<void>(radians);
}
{
/* [Deg-usage-operations] */
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
/* [Deg-usage-operations] */
static_cast<void>(b);
}
{
Double foo();
/* [Deg-usage-comparison] */
Rad angle();
Deg 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
/* [Deg-usage-comparison] */
}
{
/* [Deg-usage-conversion] */
Float sine(Rad angle);
Float a = sine(60.0_degf); // the same as sine(1.047_radf)
Degd b = 1.047_rad; // the same as 60.0_deg
Double c = Double(b); // 60.0
//Float d = a; // error, no implicit conversion
/* [Deg-usage-conversion] */
static_cast<void>(a);
static_cast<void>(c);
}
{
Float sine(Rad angle);
Float a = 60.0f;
Deg b;
/* [Deg-usage-explicit-conversion] */
//sine(a); // compilation error
sine(Deg{a}); // explicitly specifying unit
//std::sin(b); // compilation error
std::sin(Float(Rad{b})); // required explicit conversion hints to user
// that this case needs special attention
// (i.e., conversion to radians)
/* [Deg-usage-explicit-conversion] */
}
{
/* [_deg] */
using namespace Math::Literals;
Double cos1 = Math::cos(60.0_deg); // cos1 = 0.5
Double cos2 = Math::cos(1.047_rad); // cos2 = 0.5
/* [_deg] */
static_cast<void>(cos1);
static_cast<void>(cos2);
}
{
/* [_degf] */
using namespace Math::Literals;
Float tan1 = Math::tan(60.0_degf); // tan1 = 1.732f
Float tan2 = Math::tan(1.047_radf); // tan2 = 1.732f
/* [_degf] */
static_cast<void>(tan1);
static_cast<void>(tan2);
}
{
/* [Color3-pack] */
Color3 a{1.0f, 0.5f, 0.75f};
auto b = Math::pack<Color3ub>(a); // b == {255, 127, 191}
/* [Color3-pack] */
static_cast<void>(b);
}
{
/* [Color3-fromSrgb] */
Math::Vector3<UnsignedByte> srgb;
auto rgb = Color3::fromSrgb(srgb);
/* [Color3-fromSrgb] */
static_cast<void>(rgb);
}
{
Color3 color;
/* [Color3-toHsv] */
Deg hue;
Float saturation, value;
std::tie(hue, saturation, value) = color.toHsv();
/* [Color3-toHsv] */
}
{
/* [Color3-toSrgb] */
Color3 color;
Math::Vector3<UnsignedByte> srgb = color.toSrgb<UnsignedByte>();
/* [Color3-toSrgb] */
static_cast<void>(srgb);
}
{
/* [Color4-fromSrgbAlpha] */
Math::Vector4<UnsignedByte> srgbAlpha;
auto rgba = Color4::fromSrgbAlpha(srgbAlpha);
/* [Color4-fromSrgbAlpha] */
static_cast<void>(rgba);
}
{
/* [Color4-fromSrgb] */
Math::Vector3<UnsignedByte> srgb;
auto rgba = Color4::fromSrgb(srgb);
/* [Color4-fromSrgb] */
static_cast<void>(rgba);
}
{
Color4 color;
/* [Color4-toHsv] */
Deg hue;
Float saturation, value;
std::tie(hue, saturation, value) = color.toHsv();
/* [Color4-toHsv] */
}
{
/* [Color4-toSrgbAlpha] */
Color4 color;
Math::Vector4<UnsignedByte> srgbAlpha = color.toSrgbAlpha<UnsignedByte>();
/* [Color4-toSrgbAlpha] */
static_cast<void>(srgbAlpha);
}
{
/* [_rgb] */
using namespace Math::Literals;
Color3ub a = 0x33b27f_rgb; // {0x33, 0xb2, 0x7f}
/* [_rgb] */
static_cast<void>(a);
}
{
/* [_srgb] */
using namespace Math::Literals;
Math::Vector3<UnsignedByte> a = 0x33b27f_srgb; // {0x33, 0xb2, 0x7f}
/* [_srgb] */
static_cast<void>(a);
}
{
/* [_rgba] */
using namespace Math::Literals;
Color4ub a = 0x33b27fcc_rgba; // {0x33, 0xb2, 0x7f, 0xcc}
/* [_rgba] */
static_cast<void>(a);
}
{
/* [_srgba] */
using namespace Math::Literals;
Math::Vector4<UnsignedByte> a = 0x33b27fcc_srgba; // {0x33, 0xb2, 0x7f, 0xcc}
/* [_srgba] */
static_cast<void>(a);
}
{
/* [_rgbf] */
using namespace Math::Literals;
Color3 a = 0x33b27f_rgbf; // {0.2f, 0.698039f, 0.498039f}
/* [_rgbf] */
static_cast<void>(a);
}
{
/* [_srgbf] */
using namespace Math::Literals;
Color3 a = 0x33b27f_srgbf; // {0.0331048f, 0.445201f, 0.212231f}
/* [_srgbf] */
static_cast<void>(a);
}
{
/* [_rgbaf] */
using namespace Math::Literals;
Color4 a = 0x33b27fcc_rgbaf; // {0.2f, 0.698039f, 0.498039f, 0.8f}
/* [_rgbaf] */
static_cast<void>(a);
}
{
/* [_srgbaf] */
using namespace Math::Literals;
Color4 a = 0x33b27fcc_srgbaf; // {0.0331048f, 0.445201f, 0.212231f, 0.8f}
/* [_srgbaf] */
static_cast<void>(a);
}
{
/* [Half-usage] */
using namespace Math::Literals;
Half a = 3.14159_h;
Debug{} << a; // Prints 3.14159
Debug{} << Float(a); // Prints 3.14159
Debug{} << UnsignedShort(a); // Prints 25675
/* [Half-usage] */
}
{
/* [Half-usage-vector] */
Math::Vector3<Half> a{3.14159_h, -1.4142_h, 1.618_h};
Vector3 b{a}; // converts to 32-bit floats
Debug{} << a; // prints {3.14159, -1.4142, 1.618}
Debug{} << Math::Vector3<UnsignedShort>{a}; // prints {16968, 48552, 15993}
/* [Half-usage-vector] */
}
}

63
src/Magnum/Math/Angle.h

@ -49,65 +49,38 @@ and conversion less error-prone.
You can enter the value either by using a literal:
@code{.cpp}
using namespace Literals;
auto degrees = 60.0_degf; // type is Deg<Float>
auto radians = 1.047_rad; // type is Rad<Double>
@endcode
@snippet MagnumMath.cpp Deg-usage
Or explicitly convert a unitless value (such as output from some function) to
either degrees or radians:
@code{.cpp}
Double foo();
Deg<Float> degrees(35.0f);
Rad<Double> radians(foo());
//degrees = 60.0f; // error, no implicit conversion
@endcode
@snippet MagnumMath.cpp Deg-usage-convert
The classes support all arithmetic operations, such as addition, subtraction
or multiplication/division by a unitless number:
@code{.cpp}
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
@endcode
@snippet MagnumMath.cpp Deg-usage-operations
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:
@code{.cpp}
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
@endcode
@snippet MagnumMath.cpp Deg-usage-comparison
It is possible to seamlessly convert between degrees and radians and explicitly
convert the value back to the underlying type:
@code{.cpp}
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
@endcode
@snippet MagnumMath.cpp Deg-usage-conversion
@section Math-Angle-explicit-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:
reduce unit-based errors. Consider the following example that would compile
only if implicit conversions were allowed:
@code{.cpp}
namespace std { float sin(float angle); }
Float sine(Rad<Float> angle);
Float sine(Rad angle);
Float a = 60.0f; // degrees
sine(a); // silent error, sine() expected radians
@ -118,15 +91,7 @@ std::sin(b); // silent error, std::sin() expected radians
These silent errors are easily avoided by requiring explicit conversions:
@code{.cpp}
//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)
@endcode
@snippet MagnumMath.cpp Deg-usage-explicit-conversion
@see @ref Magnum::Deg, @ref Magnum::Degd
*/
@ -175,10 +140,7 @@ namespace Literals {
Example usage:
@code{.cpp}
Double cosine = Math::cos(60.0_deg); // cosine = 0.5
Double cosine = Math::cos(1.047_rad); // cosine = 0.5
@endcode
@snippet MagnumMath.cpp _deg
@see @link operator""_degf() @endlink, @link operator""_rad() @endlink
*/
@ -189,10 +151,7 @@ constexpr Deg<Double> operator "" _deg(long double value) { return Deg<Double>(D
Example usage:
@code{.cpp}
Float tangent = Math::tan(60.0_degf); // tangent = 1.732f
Float tangent = Math::tan(1.047_radf); // tangent = 1.732f
@endcode
@snippet MagnumMath.cpp _degf
@see @link operator""_deg() @endlink, @link operator""_radf() @endlink
*/

74
src/Magnum/Math/Color.h

@ -219,10 +219,7 @@ Note that constructor conversion between different types (like in @ref Vector
classes) doesn't do any (de)normalization, you should use @ref pack) and
@ref unpack() instead, for example:
@code{.cpp}
Color3 a{1.0f, 0.5f, 0.75f};
auto b = pack<Color3ub>(a); // b == {255, 127, 191}
@endcode
@snippet MagnumMath.cpp Color3-pack
Conversion from and to HSV is done always using floating-point types, so hue
is always in range in range @f$ [0.0, 360.0] @f$, saturation and value in
@ -383,10 +380,7 @@ template<class T> class Color3: public Vector3<T> {
* representation and want to create a floating-point linear RGB color
* out of it:
*
* @code{.cpp}
* Math::Vector3<UnsignedByte> srgb;
* auto rgb = Color3::fromSrgb(srgb);
* @endcode
* @snippet MagnumMath.cpp Color3-fromSrgb
*/
/* Input is a Vector3 to hint that it doesn't have any (additive,
multiplicative) semantics of a linear RGB color */
@ -475,11 +469,7 @@ template<class T> class Color3: public Vector3<T> {
*
* Example usage:
*
* @code{.cpp}
* Deg hue;
* Float saturation, value;
* std::tie(hue, saturation, value) = color.toHsv();
* @endcode
* @snippet MagnumMath.cpp Color3-toHsv
*
* @see @ref hue(), @ref saturation(), @ref value(), @ref fromHsv()
*/
@ -547,10 +537,7 @@ template<class T> class Color3: public Vector3<T> {
* Useful in cases where you have a floating-point linear RGB color and
* want to create for example an 8-bit sRGB representation out of it:
*
* @code{.cpp}
* Color3 color;
* Math::Vector3<UnsignedByte> srgb = color.toSrgb<UnsignedByte>();
* @endcode
* @snippet MagnumMath.cpp Color3-toSrgb
*/
template<class Integral> Vector3<Integral> toSrgb() const {
return Implementation::toSrgbIntegral<T, Integral>(*this);
@ -752,10 +739,7 @@ class Color4: public Vector4<T> {
* representation and want to create a floating-point linear RGBA color
* out of it:
*
* @code{.cpp}
* Math::Vector4<UnsignedByte> srgbAlpha;
* auto rgba = Color4::fromSrgbAlpha(srgbAlpha);
* @endcode
* @snippet MagnumMath.cpp Color4-fromSrgbAlpha
*/
/* Input is a Vector4 to hint that it doesn't have any (additive,
multiplicative) semantics of a linear RGB color */
@ -774,10 +758,7 @@ class Color4: public Vector4<T> {
* representation and want to create a floating-point linear RGBA color
* out of it:
*
* @code{.cpp}
* Math::Vector3<UnsignedByte> srgb;
* auto rgba = Color4::fromSrgb(srgb);
* @endcode
* @snippet MagnumMath.cpp Color4-fromSrgb
*/
/* Input is a Vector3 to hint that it doesn't have any (additive,
multiplicative) semantics of a linear RGB color */
@ -878,11 +859,7 @@ class Color4: public Vector4<T> {
* The alpha channel is not subject to any conversion, so it is
* ignored. Example usage:
*
* @code{.cpp}
* Deg hue;
* Float saturation, value;
* std::tie(hue, saturation, value) = color.toHsv();
* @endcode
* @snippet MagnumMath.cpp Color4-toHsv
*
* @see @ref hue(), @ref saturation(), @ref value(), @ref fromHsv()
*/
@ -933,10 +910,7 @@ class Color4: public Vector4<T> {
* and want to create for example an 8-bit sRGB + alpha representation
* out of it:
*
* @code{.cpp}
* Color4 color;
* Math::Vector4<UnsignedByte> srgbAlpha = color.toSrgbAlpha<UnsignedByte>();
* @endcode
* @snippet MagnumMath.cpp Color4-toSrgbAlpha
*/
template<class Integral> Vector4<Integral> toSrgbAlpha() const {
return Implementation::toSrgbAlphaIntegral<T, Integral>(*this);
@ -1012,9 +986,7 @@ namespace Literals {
Unpacks the literal into three 8-bit values. Example usage:
@code{.cpp}
Color3ub a = 0x33b27f_rgb; // {0x33, 0xb2, 0x7f}
@endcode
@snippet MagnumMath.cpp _rgb
@attention 8bit-per-channel colors are commonly treated as being in sRGB color
space, which is not directly usable in calculations and has to be converted
@ -1035,9 +1007,7 @@ Behaves identically to @link operator""_rgb() @endlink though it doesn't
return a @ref Color3 type to indicate that the resulting value is not linear
RGB. Use this literal to document that given value is in sRGB. Example usage:
@code{.cpp}
Math::Vector3<UnsignedByte> a = 0x33b27f_srgb; // {0x33, 0xb2, 0x7f}
@endcode
@snippet MagnumMath.cpp _srgb
@attention Note that colors in sRGB representation should not be used directly
in calculations --- they should be converted to linear RGB, calculation
@ -1058,9 +1028,7 @@ constexpr Vector3<UnsignedByte> operator "" _srgb(unsigned long long value) {
Unpacks the literal into four 8-bit values. Example usage:
@code{.cpp}
Color4ub a = 0x33b27fcc_rgba; // {0x33, 0xb2, 0x7f, 0xcc}
@endcode
@snippet MagnumMath.cpp _rgba
@attention 8bit-per-channel colors are commonly treated as being in sRGB color
space, which is not directly usable in calculations and has to be converted
@ -1082,9 +1050,7 @@ return a @ref Color4 type to indicate that the resulting value is not linear
RGBA. Use this literal to document that given value is in sRGB + alpha. Example
usage:
@code{.cpp}
Math::Vector4<UnsignedByte> a = 0x33b27fcc_srgba; // {0x33, 0xb2, 0x7f, 0xcc}
@endcode
@snippet MagnumMath.cpp _srgba
@attention Note that colors in sRGB representation should not be used directly
in calculations --- they should be converted to linear RGB, calculation
@ -1105,9 +1071,7 @@ constexpr Vector4<UnsignedByte> operator "" _srgba(unsigned long long value) {
Unpacks the 8-bit values into three floats. Example usage:
@code{.cpp}
Color3 a = 0x33b27f_rgbf; // {0.2f, 0.698039f, 0.498039f}
@endcode
@snippet MagnumMath.cpp _rgbf
@attention 8bit-per-channel colors are commonly treated as being in sRGB color
space, which is not directly usable in calculations and has to be converted
@ -1127,9 +1091,7 @@ Unpacks the 8-bit values into three floats and converts the color space from
sRGB to linear RGB. See @ref Color3::fromSrgb() for more information. Example
usage:
@code{.cpp}
Color3 a = 0x33b27f_srgbf; // {0.0331048f, 0.445201f, 0.212231f}
@endcode
@snippet MagnumMath.cpp _srgbf
@see @link operator""_srgbaf() @endlink, @link operator""_srgb() @endlink,
@link operator""_rgbf() @endlink
@ -1143,9 +1105,7 @@ inline Color3<Float> operator "" _srgbf(unsigned long long value) {
Unpacks the 8-bit values into four floats. Example usage:
@code{.cpp}
Color4 a = 0x33b27fcc_rgbaf; // {0.2f, 0.698039f, 0.498039f, 0.8f}
@endcode
@snippet MagnumMath.cpp _rgbaf
@attention 8bit-per-channel colors are commonly treated as being in sRGB color
space, which is not directly usable in calculations and has to be converted
@ -1165,9 +1125,7 @@ Unpacks the 8-bit values into four floats and converts the color space from
sRGB + alpha to linear RGBA. See @ref Color4::fromSrgbAlpha() for more
information. Example usage:
@code{.cpp}
Color4 a = 0x33b27fcc_srgbaf; // {0.0331048f, 0.445201f, 0.212231f, 0.8f}
@endcode
@snippet MagnumMath.cpp _srgbaf
@see @link operator""_srgbf() @endlink, @link operator""_srgba() @endlink,
@link operator""_rgbaf() @endlink

16
src/Magnum/Math/Half.h

@ -49,25 +49,13 @@ negation operator, an @link Literals::operator""_h() operator""_h() @endlink
literal and an @ref operator<<(Debug&, Half) debug operator. Internally the class uses
@ref packHalf() and @ref unpackHalf(). Example usage:
@code{.cpp}
using namespace Math::Literals;
Half a = 3.14159_h;
Debug{} << a; // Prints 3.14159
Debug{} << Float(a); // Prints 3.14159
Debug{} << UnsignedShort(a); // Prints 25675
@endcode
@snippet MagnumMath.cpp Half-usage
Note that it is also possible to use this type inside @ref Vector classes,
though, again, only for passing data around and converting them, without any
arithmetic operations:
@code{.cpp}
Math::Vector3<Half> a{3.14159_h, -1.4142_h, 1.618_h};
Vector3 b{a}; // converts to 32-bit floats
Debug{} << a; // prints {3.14159, -1.4142, 1.618}
Debug{} << Math::Vector3<UnsignedShort>{a}; // prints {16968, 48552, 15993}
@endcode
@snippet MagnumMath.cpp Half-usage-vector
@see @ref Magnum::Half
*/

Loading…
Cancel
Save