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); 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: You can enter the value either by using a literal:
@code{.cpp} @snippet MagnumMath.cpp Deg-usage
using namespace Literals;
auto degrees = 60.0_degf; // type is Deg<Float>
auto radians = 1.047_rad; // type is Rad<Double>
@endcode
Or explicitly convert a unitless value (such as output from some function) to Or explicitly convert a unitless value (such as output from some function) to
either degrees or radians: either degrees or radians:
@code{.cpp} @snippet MagnumMath.cpp Deg-usage-convert
Double foo();
Deg<Float> degrees(35.0f);
Rad<Double> radians(foo());
//degrees = 60.0f; // error, no implicit conversion
@endcode
The classes support all arithmetic operations, such as addition, subtraction The classes support all arithmetic operations, such as addition, subtraction
or multiplication/division by a unitless number: or multiplication/division by a unitless number:
@code{.cpp} @snippet MagnumMath.cpp 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
@endcode
It is also possible to compare angles with all comparison operators, but It is also possible to compare angles with all comparison operators, but
comparison of degrees and radians is not possible without explicit conversion comparison of degrees and radians is not possible without explicit conversion
to common type: to common type:
@code{.cpp} @snippet MagnumMath.cpp Deg-usage-comparison
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
It is possible to seamlessly convert between degrees and radians and explicitly It is possible to seamlessly convert between degrees and radians and explicitly
convert the value back to the underlying type: convert the value back to the underlying type:
@code{.cpp} @snippet MagnumMath.cpp Deg-usage-conversion
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
@section Math-Angle-explicit-conversion Requirement of explicit conversion @section Math-Angle-explicit-conversion Requirement of explicit conversion
The requirement of explicit conversions from and to unitless types helps to The requirement of explicit conversions from and to unitless types helps to
reduce unit-based errors. Consider following example with implicit conversions reduce unit-based errors. Consider the following example that would compile
allowed: only if implicit conversions were allowed:
@code{.cpp} @code{.cpp}
namespace std { float sin(float angle); } namespace std { float sin(float angle); }
Float sine(Rad<Float> angle); Float sine(Rad angle);
Float a = 60.0f; // degrees Float a = 60.0f; // degrees
sine(a); // silent error, sine() expected radians 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: These silent errors are easily avoided by requiring explicit conversions:
@code{.cpp} @snippet MagnumMath.cpp Deg-usage-explicit-conversion
//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
@see @ref Magnum::Deg, @ref Magnum::Degd @see @ref Magnum::Deg, @ref Magnum::Degd
*/ */
@ -175,10 +140,7 @@ namespace Literals {
Example usage: Example usage:
@code{.cpp} @snippet MagnumMath.cpp _deg
Double cosine = Math::cos(60.0_deg); // cosine = 0.5
Double cosine = Math::cos(1.047_rad); // cosine = 0.5
@endcode
@see @link operator""_degf() @endlink, @link operator""_rad() @endlink @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: Example usage:
@code{.cpp} @snippet MagnumMath.cpp _degf
Float tangent = Math::tan(60.0_degf); // tangent = 1.732f
Float tangent = Math::tan(1.047_radf); // tangent = 1.732f
@endcode
@see @link operator""_deg() @endlink, @link operator""_radf() @endlink @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 classes) doesn't do any (de)normalization, you should use @ref pack) and
@ref unpack() instead, for example: @ref unpack() instead, for example:
@code{.cpp} @snippet MagnumMath.cpp Color3-pack
Color3 a{1.0f, 0.5f, 0.75f};
auto b = pack<Color3ub>(a); // b == {255, 127, 191}
@endcode
Conversion from and to HSV is done always using floating-point types, so hue 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 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 * representation and want to create a floating-point linear RGB color
* out of it: * out of it:
* *
* @code{.cpp} * @snippet MagnumMath.cpp Color3-fromSrgb
* Math::Vector3<UnsignedByte> srgb;
* auto rgb = Color3::fromSrgb(srgb);
* @endcode
*/ */
/* Input is a Vector3 to hint that it doesn't have any (additive, /* Input is a Vector3 to hint that it doesn't have any (additive,
multiplicative) semantics of a linear RGB color */ multiplicative) semantics of a linear RGB color */
@ -475,11 +469,7 @@ template<class T> class Color3: public Vector3<T> {
* *
* Example usage: * Example usage:
* *
* @code{.cpp} * @snippet MagnumMath.cpp Color3-toHsv
* Deg hue;
* Float saturation, value;
* std::tie(hue, saturation, value) = color.toHsv();
* @endcode
* *
* @see @ref hue(), @ref saturation(), @ref value(), @ref fromHsv() * @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 * 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: * want to create for example an 8-bit sRGB representation out of it:
* *
* @code{.cpp} * @snippet MagnumMath.cpp Color3-toSrgb
* Color3 color;
* Math::Vector3<UnsignedByte> srgb = color.toSrgb<UnsignedByte>();
* @endcode
*/ */
template<class Integral> Vector3<Integral> toSrgb() const { template<class Integral> Vector3<Integral> toSrgb() const {
return Implementation::toSrgbIntegral<T, Integral>(*this); 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 * representation and want to create a floating-point linear RGBA color
* out of it: * out of it:
* *
* @code{.cpp} * @snippet MagnumMath.cpp Color4-fromSrgbAlpha
* Math::Vector4<UnsignedByte> srgbAlpha;
* auto rgba = Color4::fromSrgbAlpha(srgbAlpha);
* @endcode
*/ */
/* Input is a Vector4 to hint that it doesn't have any (additive, /* Input is a Vector4 to hint that it doesn't have any (additive,
multiplicative) semantics of a linear RGB color */ 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 * representation and want to create a floating-point linear RGBA color
* out of it: * out of it:
* *
* @code{.cpp} * @snippet MagnumMath.cpp Color4-fromSrgb
* Math::Vector3<UnsignedByte> srgb;
* auto rgba = Color4::fromSrgb(srgb);
* @endcode
*/ */
/* Input is a Vector3 to hint that it doesn't have any (additive, /* Input is a Vector3 to hint that it doesn't have any (additive,
multiplicative) semantics of a linear RGB color */ 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 * The alpha channel is not subject to any conversion, so it is
* ignored. Example usage: * ignored. Example usage:
* *
* @code{.cpp} * @snippet MagnumMath.cpp Color4-toHsv
* Deg hue;
* Float saturation, value;
* std::tie(hue, saturation, value) = color.toHsv();
* @endcode
* *
* @see @ref hue(), @ref saturation(), @ref value(), @ref fromHsv() * @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 * and want to create for example an 8-bit sRGB + alpha representation
* out of it: * out of it:
* *
* @code{.cpp} * @snippet MagnumMath.cpp Color4-toSrgbAlpha
* Color4 color;
* Math::Vector4<UnsignedByte> srgbAlpha = color.toSrgbAlpha<UnsignedByte>();
* @endcode
*/ */
template<class Integral> Vector4<Integral> toSrgbAlpha() const { template<class Integral> Vector4<Integral> toSrgbAlpha() const {
return Implementation::toSrgbAlphaIntegral<T, Integral>(*this); return Implementation::toSrgbAlphaIntegral<T, Integral>(*this);
@ -1012,9 +986,7 @@ namespace Literals {
Unpacks the literal into three 8-bit values. Example usage: Unpacks the literal into three 8-bit values. Example usage:
@code{.cpp} @snippet MagnumMath.cpp _rgb
Color3ub a = 0x33b27f_rgb; // {0x33, 0xb2, 0x7f}
@endcode
@attention 8bit-per-channel colors are commonly treated as being in sRGB color @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 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 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: RGB. Use this literal to document that given value is in sRGB. Example usage:
@code{.cpp} @snippet MagnumMath.cpp _srgb
Math::Vector3<UnsignedByte> a = 0x33b27f_srgb; // {0x33, 0xb2, 0x7f}
@endcode
@attention Note that colors in sRGB representation should not be used directly @attention Note that colors in sRGB representation should not be used directly
in calculations --- they should be converted to linear RGB, calculation 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: Unpacks the literal into four 8-bit values. Example usage:
@code{.cpp} @snippet MagnumMath.cpp _rgba
Color4ub a = 0x33b27fcc_rgba; // {0x33, 0xb2, 0x7f, 0xcc}
@endcode
@attention 8bit-per-channel colors are commonly treated as being in sRGB color @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 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 RGBA. Use this literal to document that given value is in sRGB + alpha. Example
usage: usage:
@code{.cpp} @snippet MagnumMath.cpp _srgba
Math::Vector4<UnsignedByte> a = 0x33b27fcc_srgba; // {0x33, 0xb2, 0x7f, 0xcc}
@endcode
@attention Note that colors in sRGB representation should not be used directly @attention Note that colors in sRGB representation should not be used directly
in calculations --- they should be converted to linear RGB, calculation 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: Unpacks the 8-bit values into three floats. Example usage:
@code{.cpp} @snippet MagnumMath.cpp _rgbf
Color3 a = 0x33b27f_rgbf; // {0.2f, 0.698039f, 0.498039f}
@endcode
@attention 8bit-per-channel colors are commonly treated as being in sRGB color @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 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 sRGB to linear RGB. See @ref Color3::fromSrgb() for more information. Example
usage: usage:
@code{.cpp} @snippet MagnumMath.cpp _srgbf
Color3 a = 0x33b27f_srgbf; // {0.0331048f, 0.445201f, 0.212231f}
@endcode
@see @link operator""_srgbaf() @endlink, @link operator""_srgb() @endlink, @see @link operator""_srgbaf() @endlink, @link operator""_srgb() @endlink,
@link operator""_rgbf() @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: Unpacks the 8-bit values into four floats. Example usage:
@code{.cpp} @snippet MagnumMath.cpp _rgbaf
Color4 a = 0x33b27fcc_rgbaf; // {0.2f, 0.698039f, 0.498039f, 0.8f}
@endcode
@attention 8bit-per-channel colors are commonly treated as being in sRGB color @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 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 sRGB + alpha to linear RGBA. See @ref Color4::fromSrgbAlpha() for more
information. Example usage: information. Example usage:
@code{.cpp} @snippet MagnumMath.cpp _srgbaf
Color4 a = 0x33b27fcc_srgbaf; // {0.0331048f, 0.445201f, 0.212231f, 0.8f}
@endcode
@see @link operator""_srgbf() @endlink, @link operator""_srgba() @endlink, @see @link operator""_srgbf() @endlink, @link operator""_srgba() @endlink,
@link operator""_rgbaf() @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 literal and an @ref operator<<(Debug&, Half) debug operator. Internally the class uses
@ref packHalf() and @ref unpackHalf(). Example usage: @ref packHalf() and @ref unpackHalf(). Example usage:
@code{.cpp} @snippet MagnumMath.cpp 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
@endcode
Note that it is also possible to use this type inside @ref Vector classes, 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 though, again, only for passing data around and converting them, without any
arithmetic operations: arithmetic operations:
@code{.cpp} @snippet MagnumMath.cpp 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}
@endcode
@see @ref Magnum::Half @see @ref Magnum::Half
*/ */

Loading…
Cancel
Save