From d939221f7f5f9f567c90a499d732e4b07f0af118 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 13 Feb 2022 12:02:17 +0100 Subject: [PATCH] doc: refresh various math docs a bit. --- doc/matrix-vector.dox | 176 +++++++++++++++++++----------------- doc/snippets/MagnumMath.cpp | 79 ++++++++++------ doc/types.dox | 65 +++++++------ src/Magnum/Math/Color.h | 12 +-- src/Magnum/Math/Half.h | 13 +-- 5 files changed, 194 insertions(+), 151 deletions(-) diff --git a/doc/matrix-vector.dox b/doc/matrix-vector.dox index 48de7e0fe..9d3f24fed 100644 --- a/doc/matrix-vector.dox +++ b/doc/matrix-vector.dox @@ -33,56 +33,56 @@ namespace Magnum { @m_footernavigation Matrices and vectors are the most important part of graphics programming and -one of goals of Magnum is to make their usage as intuitive as possible. They -are contained in @ref Math namespace and common variants also have aliases in -root @ref Magnum namespace. See the documentation of these namespaces for more -information about usage with CMake. +one of Magnum goals is to make their usage as intuitive as possible. @section matrix-vector-hierarchy Matrix and vector classes -Magnum has three main matrix and vector classes: @ref Math::RectangularMatrix, -(square) @ref Math::Matrix and @ref Math::Vector. To maximize code reuse, -@ref Math::Matrix is internally square @ref Math::RectangularMatrix and -@ref Math::RectangularMatrix is internally array of one or more @ref Math::Vector -instances. Both vectors and matrices can have arbitrary size (known at compile -time) and can store any arithmetic type. - -Each subclass brings some specialization to its superclass. For the most common -vector and matrix sizes there are specialized classes @ref Math::Matrix3 and -@ref Math::Matrix4, implementing various transformations in 2D and 3D and -@ref Math::Vector2, @ref Math::Vector3 and @ref Math::Vector4, implementing -direct access to named components. Functions of each class try to return the -most specialized type known to make subsequent operations more convenient --- -columns of @ref Math::RectangularMatrix are returned as @ref Math::Vector, but -when accessing columns of e.g. @ref Math::Matrix3, they are returned as +Magnum has three main matrix and vector classes --- a +@ref Math::RectangularMatrix, a (square) @ref Math::Matrix and a +@ref Math::Vector. To maximize code reuse, the @ref Math::Matrix is internally +a square @ref Math::RectangularMatrix and a @ref Math::RectangularMatrix is +internally an array of one or more @ref Math::Vector instances. Both vectors +and matrices can have arbitrary size (known at compile time) and can store any +arithmetic type, including a @ref Half or e.g. a @ref Rad. + +Each subclass brings some specialization to its superclass. The +@ref Math::Vector2, @ref Math::Vector3 and @ref Math::Vector4 classes implement +direct access to named components, @ref Math::Matrix adds determinant +calculation or matrix inversion and @ref Math::Matrix3 / @ref Math::Matrix4 +implement 2D and 3D transformations. Functions of each class return the most +specialized type known to make subsequent operations more convenient --- +columns of @ref Math::RectangularMatrix are returned as a @ref Math::Vector, +but when accessing columns of e.g. @ref Math::Matrix3, they are returned as a @ref Math::Vector3. There are also even more specialized subclasses, e.g. @ref Math::Color3 and @ref Math::Color4 for color handling and conversion. -Commonly used types have convenience aliases in @ref Magnum namespace, so you -can write e.g. @ref Vector3i instead of @ref Math::Vector3 "Math::Vector3". -See @ref types and @ref Magnum namespace documentation for more information. +Commonly used types have convenience aliases in the @ref Magnum namespace, so +you can write e.g. @ref Vector3i instead of +@ref Math::Vector3 "Math::Vector3". See @ref types and the @ref Magnum +namespace documentation for more information. @section matrix-vector-construction Constructing matrices and vectors -The default constructors of @ref Math::RectangularMatrix and @ref Math::Vector (and -@ref Math::Vector2, @ref Math::Vector3, @ref Math::Vector4, @ref Math::Color3, -@ref Math::Color4) create zero-filled objects. @ref Math::Matrix (and -@ref Math::Matrix3, @ref Math::Matrix4) is by default constructed as an identity -matrix. +The default constructors of @ref Math::RectangularMatrix and @ref Math::Vector +(and @ref Math::Vector2, @ref Math::Vector3, @ref Math::Vector4, +@ref Math::Color3, @ref Math::Color4) create zero-filled objects, equivalent +to using the @ref Math::ZeroInit tag. @ref Math::Matrix (and +@ref Math::Matrix3, @ref Math::Matrix4) is by default constructed as an +identity matrix, equivalent to using the @ref Math::IdentityInit tag. @snippet MagnumMath.cpp matrix-vector-construct -The most common and most efficient way to create a vector is to pass all values to -the constructor. A matrix is created by passing all the column vectors to the -constructor. These constructors check the number of passed arguments and errors -are caught at compile time. +The most common and most efficient way to create a vector is to pass all values +to the constructor. A matrix is created by passing all *column* vectors to the +constructor. The constructors check correct number of passed arguments at +compile time. @snippet MagnumMath.cpp matrix-vector-construct-value -You can specify all components of vectors or the diagonal of a square matrix -with a single value or create a diagonal matrix from a vector: +You can specify all components of a vector or a matrix with a single value, or +specify just values on the matrix diagonal: @snippet MagnumMath.cpp matrix-vector-construct-diagonal @@ -92,26 +92,31 @@ zero or one which are useful for transformations: @snippet MagnumMath.cpp matrix-vector-construct-axis It is also possible to create matrices and vectors from a C-style array. The -function performs a simple type cast without copying anything, so it's possible to -conveniently operate on the array itself: +function performs a simple type cast without copying anything, so it's possible +to conveniently operate on the array itself: @snippet MagnumMath.cpp matrix-vector-construct-from @attention Note that, unlike a constructor, this function has no way to check - whether the array is long enough to contain all the elements, so use it with - caution. + whether the array is long enough to contain all the elements, so use it + with caution. To make handling colors easier, their behavior is a bit different with a -richer feature set. Implicit construction of @ref Color4 from @ref Color3 will -set the alpha to the max value (thus @cpp 1.0f @ce for @ref Color4 and @cpp 255 @ce -for @ref Color4ub): +richer feature set. Implicit construction of @ref Math::Color4 from just the +RGB components will set the alpha to the max value (thus @cpp 1.0f @ce for +@ref Color4 and @cpp 255 @ce for @ref Color4ub): @snippet MagnumMath.cpp matrix-vector-construct-color -Similar to axes in vectors, you can create single color shades too, or create -a RGB color from a HSV representation: +Similar to axes and scales in vectors, you can create single color shades too: -@snippet MagnumMath.cpp matrix-vector-construct-color-hue +@snippet MagnumMath.cpp matrix-vector-construct-color-axis + +There are also builtin colorspace conversion functions --- it's possible to +create a RGB color from a HSV value, a linear color value from a sRGB +representation, or convert from CIE XYZ / xyY. And the other way as well: + +@snippet MagnumMath.cpp matrix-vector-construct-color-colorspace Finally, the namespace @ref Math::Literals provides convenient @link Literals::operator""_rgb() operator""_rgb() @endlink / @@ -130,51 +135,49 @@ documentation for more information. @section matrix-vector-component-access Accessing matrix and vector components -Column vectors of matrices and vector components can be accessed using square -brackets: +Column vectors of matrices and components of vectors can be accessed using +square brackets: @snippet MagnumMath.cpp matrix-vector-access Row vectors can be accessed too, but only for reading, and access is slower -due to the way the matrix is stored (see @ref matrix-vector-column-major "explanation below"): +due to the matrix being stored @ref matrix-vector-column-major "in column-major order": @snippet MagnumMath.cpp matrix-vector-access-row Fixed-size vector subclasses have functions for accessing named components -and subparts: +and subparts using either `xyzw` or `rgba`: @snippet MagnumMath.cpp matrix-vector-access-named -@ref Color3 and @ref Color4 name their components `rgba` instead of `xyzw`. - -For more involved operations with components there is the @ref Math::gather() +For more involved operations with components there are the @ref Math::gather() and @ref Math::scatter() functions: @snippet MagnumMath.cpp matrix-vector-access-swizzle @section matrix-vector-conversion Converting between different underlying types -All vector, matrix and other classes in @ref Math namespace can be -constructed from an instance with a different underlying type (e.g. convert -between integer and floating-point or betweeen @ref Float and @ref Double). -Unlike with plain C++ data types, the conversion is done via an *explicit* -constructor. That might sound inconvenient, but performing the conversion -explicitly avoids common issues like precision loss (or, on the other hand, -expensive computation with unnecessarily high precision). +All classes in @ref Math namespace can be constructed from an instance with a +different underlying type (e.g. convert between integer and floating-point type +or betweeen @ref Float, @ref Double and @ref Half). Unlike with plain C++ data +types, the conversion is *explicit*. That might sound inconvenient at first, +but performing the conversion explicitly avoids common issues like precision +loss (or, on the other hand, expensive computation with unnecessarily high +precision). -To further emphasise the intent of conversion (so it doesn't look like an accident -or a typo), you are encouraged to use @cpp auto b = Type{a} @ce instead of -@cpp Type b{a} @ce. +To further emphasise the intent of conversion (so it doesn't look like an +accident or a typo), you are encouraged to use @cpp auto b = Type{a} @ce +instead of @cpp Type b{a} @ce. @snippet MagnumMath.cpp matrix-vector-convert -For packing and unpacking use the @ref Math::pack() and @ref Math::unpack() -functions: +For packing floats into integers and unpacking them back use the +@ref Math::pack() and @ref Math::unpack() functions: @snippet MagnumMath.cpp matrix-vector-convert-pack -See @ref matrix-vector-componentwise "below" for more information about other -available component-wise operations. +See below for more information about other available +@ref matrix-vector-componentwise "component-wise operations". @section matrix-vector-operations Operations with matrices and vectors @@ -189,10 +192,10 @@ As in GLSL, vectors can be also multiplied or divided component-wise: @snippet MagnumMath.cpp matrix-vector-operations-multiply When working with integral vectors (i.e. 24bit RGB values), it is often -desirable to multiply them with floating-point values but retain an integral result. -In Magnum, all multiplication/division operations involving integral vectors -will return integers within the result, you need to convert both arguments to the same -floating-point type to have floating-point result. +desirable to multiply them with floating-point values but retain an integral +result. In Magnum, all multiplication/division operations involving integral +vectors will return an integer result, you need to convert both arguments to +the same floating-point type to have a floating-point result. @snippet MagnumMath.cpp matrix-vector-operations-integer @@ -205,16 +208,16 @@ Matrices can be added, subtracted and multiplied with matrix multiplication. @snippet MagnumMath.cpp matrix-vector-operations-matrix You can also multiply (properly sized) vectors with matrices. These operations -are just convenience shortcuts for multiplying with single-column matrices: +are equivalent to multiplying with single-column matrices: @snippet MagnumMath.cpp matrix-vector-operations-multiply-matrix @section matrix-vector-componentwise Component-wise and inter-vector operations As shown above, vectors can be added and multiplied component-wise using the -@cpp + @ce or @cpp * @ce operator. You can use @ref Math::Vector::sum() "sum()" -and @ref Math::Vector::product() "product()" for sum or product of components -in one vector: +@cpp + @ce or @cpp * @ce operator. For a sum or product of components *inside* +a vector you can use @ref Math::Vector::sum() "sum()" and +@ref Math::Vector::product() "product()" instead: @snippet MagnumMath.cpp matrix-vector-operations-componentwise @@ -225,19 +228,21 @@ Component-wise minimum and maximum of two vectors can be done using @snippet MagnumMath.cpp matrix-vector-operations-minmax -The vectors can be also compared component-wise, the result is returned in +The vectors can be also compared component-wise, the result is returned in a @ref Math::BoolVector class: @snippet MagnumMath.cpp matrix-vector-operations-compare There are also function for component-wise rounding, sign operations, square -root, various interpolation and (de)normalization functionality: +root and various interpolation and (de)normalization functionality: @snippet MagnumMath.cpp matrix-vector-operations-functions Component-wise functions are implemented only for vectors and not for matrices -to keep the math library a sane and maintainable size. Instead, you can -reinterpret the matrix as vector and do the operation on it (and vice versa): +to keep the math library in a sane and maintainable size. Instead, you can +reinterpret the matrix as a vector and do the operation on it (and vice versa) +--- because you get a reference that way, the operation will affect the +original data: @snippet MagnumMath.cpp matrix-vector-operations-functions-componentwise @@ -250,11 +255,20 @@ For types with units the only exception are power functions such as @ref Math::pow() or @ref Math::log() --- the resulting unit of such an operation cannot be represented and thus will only work on unitless types. +@section matrix-vector-linear-algebra Linear algebra operations + +Also available are common linear algebra operations --- the dot or cross +product, vector, reflection or angle calculation. These are mostly available +as free functions in the @ref Math namespace, with more advanced functionality +such as QR or SVD decomposition in @ref Math::Algorithms. + +@snippet MagnumMath.cpp matrix-vector-linear-algebra + @section matrix-vector-column-major Matrices are column-major and vectors are columns -OpenGL matrices are column-major, thus in Magnum it is reasonable to use matrices -also as column-major (the vectors are the columns). This naturally has some -implications and it may differ from what is common in mathematics: +For consistency with GLSL, Magnum stores matrices as column-major (the vectors +are columns). This naturally has some implications and it may differ from what +you're used to from linear algebra or other graphics toolkits:
  • Order of template arguments in specification of @ref Math::RectangularMatrix @@ -268,8 +282,8 @@ implications and it may differ from what is common in mathematics: @snippet MagnumMath.cpp matrix-vector-column-major-construct
  • Element access order is also column-major, thus the bracket operator - accesses columns. The returned vector also has its own bracket operator, which - then indexes rows. + accesses columns. The returned vector also has its own bracket operator, + which then indexes rows. @snippet MagnumMath.cpp matrix-vector-column-major-access
  • diff --git a/doc/snippets/MagnumMath.cpp b/doc/snippets/MagnumMath.cpp index e32ee1dbb..73987df5e 100644 --- a/doc/snippets/MagnumMath.cpp +++ b/doc/snippets/MagnumMath.cpp @@ -49,16 +49,18 @@ using namespace Magnum::Math::Literals; int main() { { /* [matrix-vector-construct] */ -Matrix2x3 a; // zero-filled -Vector3i b; // zero-filled +Matrix2x3 a; // zero-filled +Vector3i b; // zero-filled -Matrix3 identity; // diagonal set to 1 -Matrix3 zero{Math::ZeroInit}; // zero-filled +Matrix3 c; // diagonal set to 1.0f +Matrix3 d{Math::IdentityInit}; // diagonal set to 1.0f +Matrix3 e{Math::ZeroInit}; // zero-filled /* [matrix-vector-construct] */ static_cast(a); static_cast(b); -static_cast(identity); -static_cast(zero); +static_cast(c); +static_cast(d); +static_cast(e); } { @@ -76,7 +78,7 @@ static_cast(mat); { /* [matrix-vector-construct-diagonal] */ Matrix3 diag{Math::IdentityInit, 2.0f}; // diagonal is 2.0f, zeros elsewhere -Vector3i fill(10); // {10, 10, 10} +Vector3i fill{10}; // {10, 10, 10} auto diag2 = Matrix3::fromDiagonal({3.0f, 2.0f, 1.0f}); /* [matrix-vector-construct-diagonal] */ static_cast(diag); @@ -105,29 +107,38 @@ Math::Matrix2x3::from(mat) *= 2; // { 4, 8, 12, 2, 6, 10 } { /* [matrix-vector-construct-color] */ -Color4 a = Color3{0.2f, 0.7f, 0.5f}; // {0.2f, 0.7f, 0.5f, 1.0f} -Color4ub b = Color3ub{0x33, 0xb2, 0x7f}; // {0x33, 0xb2, 0x7f, 0xff} +Color4 a = Color3{0.2f, 0.7f, 0.5f}; // {0.2f, 0.7f, 0.5f, 1.0f} +Color4ub b = Color3ub{0x33, 0xb2, 0x7f}; // {0x33, 0xb2, 0x7f, 0xff} /* [matrix-vector-construct-color] */ static_cast(a); static_cast(b); } { -/* [matrix-vector-construct-color-hue] */ -auto green = Color3::green(); // {0.0f, 1.0f, 0.0f} -auto cyan = Color4::cyan(0.5f, 0.95f); // {0.5f, 1.0f, 1.0f, 0.95f} -auto fadedRed = Color3::fromHsv({219.0_degf, 0.50f, 0.57f}); -/* [matrix-vector-construct-color-hue] */ +/* [matrix-vector-construct-color-axis] */ +auto green = Color3::green(); // {0.0f, 1.0f, 0.0f} +auto cyan = Color4::cyan(0.5f, 0.95f); // {0.5f, 1.0f, 1.0f, 0.95f} +/* [matrix-vector-construct-color-axis] */ static_cast(green); static_cast(cyan); +} + +{ +/* [matrix-vector-construct-color-colorspace] */ +auto fadedRed = Color3::fromHsv({219.0_degf, 0.50f, 0.57f}); +auto linear = Color3::fromSrgb(0x33b27f); // {0.2f, 0.7f, 0.5f} +auto white = Color3::fromXyz({0.950456f, 1.0f, 1.08906f}); +UnsignedInt srgb = linear.toSrgbInt(); // 0x33b27f +/* [matrix-vector-construct-color-colorspace] */ static_cast(fadedRed); +static_cast(linear); } { /* [matrix-vector-construct-color-literal] */ -Color3ub a = 0x33b27f_rgb; // {0x33, 0xb2, 0x7f} -Color4 b = 0x33b27fcc_rgbaf; // {0.2f, 0.7f, 0.5f, 0.8f} -Color4 c = 0x33b27fcc_srgbaf; // {0.0331048f, 0.445201f, 0.212231f, 0.8f} +Color3ub a = 0x33b27f_rgb; // {0x33, 0xb2, 0x7f} +Color4 b = 0x33b27fcc_rgbaf; // {0.2f, 0.7f, 0.5f, 0.8f} +Color4 c = 0x33b27fcc_srgbaf; // {0.0331048f, 0.445201f, 0.212231f, 0.8f} /* [matrix-vector-construct-color-literal] */ static_cast(a); static_cast(b); @@ -137,15 +148,15 @@ static_cast(c); { /* [matrix-vector-access] */ Matrix3x2 a; -a[2] /= 2.0f; // third column (column major indexing, see explanation below) -a[0][1] = 5.3f; // first column, second element +a[2] /= 2.0f; // third column +a[0][1] = 5.3f; // first column, second element Vector3i b; -b[1] = 1; // second element +b[1] = 1; // second element /* [matrix-vector-access] */ /* [matrix-vector-access-row] */ -Vector3 c = a.row(1); // second row +Vector3 c = a.row(1); // second row /* [matrix-vector-access-row] */ static_cast(c); } @@ -165,13 +176,13 @@ static_cast(x); { /* [matrix-vector-access-swizzle] */ Vector4i orig{-1, 2, 3, 4}; -Vector4i bgra = Math::gather<'b', 'g', 'r', 'a'>(orig); // { 3, 2, -1, 4 } +Vector4i bgra = Math::gather<'b', 'g', 'r', 'a'>(orig); // {3, 2, -1, 4} Math::Vector<6, Int> w10xyz = Math::gather<'w', '1', '0', 'x', 'y', 'z'>(orig); - // { 4, 1, 0, -1, 2, 3 } + // {4, 1, 0, -1, 2, 3} Vector4 vec{1.5f, 3.0f, 0.1f, 1.1f}; Vector2 coords{5.0f, -2.0f}; -Math::scatter<'z', 'w'>(vec, coords); // { 1.5, 3.0, 5.0, -2.0 } +Math::scatter<'z', 'w'>(vec, coords); // {1.5f, 3.0f, 5.0f, -2.0f} /* [matrix-vector-access-swizzle] */ static_cast(bgra); @@ -204,7 +215,7 @@ static_cast(d); { /* [matrix-vector-operations-vector] */ Vector3 a{1.0f, 2.0f, 3.0f}; -Vector3 b = a*5.0f - Vector3{3.0f, -0.5f, -7.5f}; // {5.0f, 9.5f, 7.5f} +Vector3 b = a*5.0f - Vector3{3.0f, 0.5f, 7.5f}; // {2.0f, 9.5f, 7.5f} Vector3 c = 1.0f/a; // {1.0f, 0.5f, 0.333f} /* [matrix-vector-operations-vector] */ static_cast(b); @@ -272,8 +283,8 @@ static_cast(e); { /* [matrix-vector-operations-componentwise] */ -Float a = Vector3{1.5f, 0.3f, 8.0f}.sum(); // 8.8f -Int b = Vector3i{32, -5, 7}.product(); // 1120 +Float a = Vector3{1.5f, 0.3f, 8.0f}.sum(); // 9.8f +Int b = Vector3i{32, -5, 7}.product(); // -1120 /* [matrix-vector-operations-componentwise] */ static_cast(a); static_cast(b); @@ -302,9 +313,9 @@ static_cast(allLarger); { /* [matrix-vector-operations-functions] */ -Vector3 a{5.5f, -0.3f, 75.0f}; -Vector3 b = Math::round(a); // {5.0f, 0.0f, 75.0f} -Vector3 c = Math::abs(a); // {5.5f, -0.3f, 75.0f} +Vector3 a{5.5f, -0.3f, 75.1f}; +Vector3 b = Math::round(a); // {6.0f, 0.0f, 75.0f} +Vector3 c = Math::abs(a); // {5.5f, -0.3f, 75.1f} Vector3 d = Math::clamp(a, -0.2f, 55.0f); // {5.5f, -0.2f, 55.0f} /* [matrix-vector-operations-functions] */ static_cast(b); @@ -336,6 +347,14 @@ static_cast(b); static_cast(c); } +{ +/* [matrix-vector-linear-algebra] */ +Float zero = Math::dot(Vector3::xAxis(), Vector3::yAxis()); +Vector3 zAxis = Math::cross(Vector3::xAxis(), Vector3::yAxis()); +Deg ninety = Math::angle(Vector3::xAxis(), Vector3::zAxis()); +/* [matrix-vector-linear-algebra] */ +} + { /* [matrix-vector-column-major-template] */ Math::RectangularMatrix<2, 5, Int> mat; // two columns, five rows diff --git a/doc/types.dox b/doc/types.dox index 6b055bb46..5dd498728 100644 --- a/doc/types.dox +++ b/doc/types.dox @@ -42,7 +42,7 @@ Magnum provides its own typedefs for builtin integral and floating-point arithmetic types to ensure portability, maintain consistency and reduce confusion. E.g., the @ref Int typedef is guaranteed to *always* be 32-bit and Magnum's own code and documentation prefers to use it over a wild mixture of -@ref std::int32_t, @cpp int @ce, @cpp GLint @ce and @cpp ALint @ce that all +@ref std::int32_t, @cpp int @ce, @cpp GLint @ce or @cpp ALint @ce that all refer to the same type. | Magnum type | Size | Equivalent GLSL type | @@ -128,25 +128,44 @@ about the differences. Scalar types with a GLSL equivalent are guaranteed to have exactly the same binary representation. Consequently, matrix and vector classes also have the same binary representation as corresponding array of numeric values without any -additional data or padding (e.g. @cpp sizeof(Vector3i) == sizeof(Int[3]) @ce), -all matrices are stored in column-major order. +additional data or padding (e.g. @cpp sizeof(Vector3i) == sizeof(Int[3]) @ce). +All matrices are stored in column-major order. This means that all scalar, matrix and vector types can be used directly for filling GPU buffers and textures without any need for data extraction or -conversion. For convenience all vector and matrix classes provide -@ref Math::RectangularMatrix::data() "data()" function, which returns pointer +conversion. For convenience all vector and matrix classes provide a +@ref Math::RectangularMatrix::data() "data()" function, which returns a pointer to the internal data array. +@section types-half Half-precision arithmetic + +The @ref Half type represents half-precision floating point values. The sole +purpose of the type is to make creation, conversion and visualization of +half-float values easier. By design it doesn't support any arithmetic +operations as not all CPU architecture have native support for half-floats and +thus the operations would be done faster in a regular single-precision +@ref Float. The class provides explicit constructors and conversion operators +from/to @ref Float and @ref UnsignedShort and you can also use the +@link Math::Literals::operator""_h() _h @endlink literal that is provided in +the @ref Math::Literals namespace: + +@snippet MagnumMath.cpp types-literals-half + +Half-precision vector and matrix types such as @ref Vector3h or @ref Matrix3x3h +work similarly --- you can construct them and convert them from/to other types, +but can't perform any arithmetic. + @section types-special Special types -Magnum has special type for strongly-typed representation of angles, namely -the @ref Deg and @ref Rad classes (or @ref Degd and @ref Radd with @ref Double -as underlying type). Their only purpose is to avoid common degree-vs-radian -bugs (i.e. entering degree value where radians should be) and make the -conversion between these two representations easier. They are just a tiny -@cpp constexpr @ce wrapper around the native type and they support all -meaningful numeric operations, so using them won't have any performance or -usability impact in practice. +Magnum has a special type for strongly-typed representation of angles, namely +the @ref Deg and @ref Rad classes (or @ref Degd / @ref Degh and @ref Radd / +@ref Radh with @ref Double / @ref Half as underlying type). Their purpose is to +avoid common degree-vs-radian bugs (i.e. entering a degree value where radians +should be and vice versa) and make the conversion between these two +representations easier. They are just a tiny @cpp constexpr @ce wrapper around +the native type and they support all meaningful numeric operations. The wrapper +API may have a slight overhead on debug builds, but the safety benefits +outweight that in most practical use cases. These classes are *not* implicitly constructible or convertible from/to @ref Float or @ref Double, you have to either construct/convert them explicitly @@ -170,16 +189,6 @@ any need to care about what input the function expects: @snippet MagnumMath.cpp types-literals-usage -There is also a @ref Half type for handling half-precision floating point -values. By design it doesn't support any arithmetic operations as they would be -done faster on single-precision, it's sole purpose is to make working with -half-float values easier. It provides either explicit constructors and -conversion operators from/to @ref Float and @ref UnsignedShort and you can also -use the @link Math::Literals::operator""_h() _h @endlink literal that is -provided in the @ref Math::Literals namespace: - -@snippet MagnumMath.cpp types-literals-half - @section types-other Other types Other types, which don't have their GLSL equivalent, are: @@ -203,22 +212,22 @@ These types can be used in GLSL either by extracting values from their underlying structure or converting them to types supported by GLSL (e.g. quaternion to matrix). -For your convenience, there is also alias for class with often used constants ---- @ref Constants or @ref Constantsd. +For your convenience, there is also a structure with often used constants +--- @ref Constants, or @ref Constantsd for the double-precision variants. @section types-initialization Initialization Vectors, general matrices and range types are by default zero-initialized, transformation types (square matrices, (dual) complex numbers and quaternions) are set to identity transformation. It is possible to initialize the instances -differently using so-called *tags* or use the *tag* to make the choice appear +differently using so-called *tags* or use the tag to make the choice appear explicit: - @ref Math::ZeroInit zero-initializes the contents (works for all types). - @ref Math::IdentityInit initializes the contents to identity transformation (works only for transformation types, where it is also the default). -- @ref Math::NoInit leaves the contents uninitialized (useful if you will - overwrite the contents anyway, works for all types). +- @ref NoInit leaves the contents uninitialized (useful if you will overwrite + the contents anyway, works for all types). Example: diff --git a/src/Magnum/Math/Color.h b/src/Magnum/Math/Color.h index 8f51eca3b..6984e8c4d 100644 --- a/src/Magnum/Math/Color.h +++ b/src/Magnum/Math/Color.h @@ -433,7 +433,7 @@ template class Color3: public Vector3 { } /** - * @brief Create RGB color from CIE XYZ representation + * @brief Create RGB color from [CIE XYZ representation](https://en.wikipedia.org/wiki/CIE_1931_color_space) * @param xyz Color in CIE XYZ color space * * Applies transformation matrix, returning the input in linear @@ -596,7 +596,7 @@ template class Color3: public Vector3 { } /** - * @brief Convert to CIE XYZ representation + * @brief Convert to [CIE XYZ representation](https://en.wikipedia.org/wiki/CIE_1931_color_space) * * Assuming the color is in linear RGB with D65 illuminant and 2° * standard colorimetric observer, applies transformation matrix, @@ -850,7 +850,7 @@ class Color4: public Vector4 { } /** - * @brief Create RGBA color from CIE XYZ representation + * @brief Create RGBA color from [CIE XYZ representation](https://en.wikipedia.org/wiki/CIE_1931_color_space) * @param xyz Color in CIE XYZ color space * @param a Alpha value, defaults to @cpp 1.0 @ce for * floating-point types and maximum positive value for integral @@ -1008,7 +1008,7 @@ class Color4: public Vector4 { } /** - * @brief Convert to CIE XYZ representation + * @brief Convert to [CIE XYZ representation](https://en.wikipedia.org/wiki/CIE_1931_color_space) * * Assuming the color is in linear RGB, applies transformation matrix, * returning the color in CIE XYZ color space. The alpha channel is not @@ -1037,7 +1037,7 @@ class Color4: public Vector4 { }; /** @relatesalso Color3 -@brief Convert color from CIE xyY representation to CIE XYZ +@brief Convert color from [CIE xyY representation](https://en.wikipedia.org/wiki/CIE_1931_color_space#CIE_xy_chromaticity_diagram_and_the_CIE_xyY_color_space) to CIE XYZ @f[ \begin{array}{rcl} @@ -1052,7 +1052,7 @@ template inline Vector3 xyYToXyz(const Vector3& xyY) { } /** @relatesalso Color3 -@brief Convert color from CIE XYZ representation to CIE xyY +@brief Convert color from CIE XYZ representation to [CIE xyY](https://en.wikipedia.org/wiki/CIE_1931_color_space#CIE_xy_chromaticity_diagram_and_the_CIE_xyY_color_space) @f[ \begin{array}{rcl} diff --git a/src/Magnum/Math/Half.h b/src/Magnum/Math/Half.h index 8b4200dc5..f4ac008ad 100644 --- a/src/Magnum/Math/Half.h +++ b/src/Magnum/Math/Half.h @@ -49,12 +49,13 @@ MAGNUM_EXPORT Float unpackHalf(UnsignedShort value); /** @brief Half-precision float literal -The purpose of this class is just to make specifying and printing of half-float -literals easier. By design no arithmetic operations are supported, as majority -of CPUs has no dedicated instructions for half-precision floats and thus it is -faster to just use regular single-precision @ref Magnum::Float "Float". See -[Wikipedia](https://en.wikipedia.org/wiki/Half-precision_floating-point_format) -for more information about half floats. +Represents a floating-point value in the [`binary16` format](https://en.wikipedia.org/wiki/Half-precision_floating-point_format). + +The sole purpose of this type is to make creation, conversion and visualization +of half-float values easier. By design it doesn't support any arithmetic +operations as not all CPU architecture have native support for half-floats and +thus the operations would be done faster in a regular single-precision +@ref Magnum::Float "Float". The class provides explicit conversion from and to @ref Magnum::Float "Float", equality comparison with correct treatment of NaN values, promotion and