Browse Source

doc: refresh various math docs a bit.

pull/240/merge
Vladimír Vondruš 4 years ago
parent
commit
d939221f7f
  1. 176
      doc/matrix-vector.dox
  2. 79
      doc/snippets/MagnumMath.cpp
  3. 65
      doc/types.dox
  4. 12
      src/Magnum/Math/Color.h
  5. 13
      src/Magnum/Math/Half.h

176
doc/matrix-vector.dox

@ -33,56 +33,56 @@ namespace Magnum {
@m_footernavigation @m_footernavigation
Matrices and vectors are the most important part of graphics programming and 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 one of Magnum goals is to make their usage as intuitive as possible.
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.
@section matrix-vector-hierarchy Matrix and vector classes @section matrix-vector-hierarchy Matrix and vector classes
Magnum has three main matrix and vector classes: @ref Math::RectangularMatrix, Magnum has three main matrix and vector classes --- a
(square) @ref Math::Matrix and @ref Math::Vector. To maximize code reuse, @ref Math::RectangularMatrix, a (square) @ref Math::Matrix and a
@ref Math::Matrix is internally square @ref Math::RectangularMatrix and @ref Math::Vector. To maximize code reuse, the @ref Math::Matrix is internally
@ref Math::RectangularMatrix is internally array of one or more @ref Math::Vector a square @ref Math::RectangularMatrix and a @ref Math::RectangularMatrix is
instances. Both vectors and matrices can have arbitrary size (known at compile internally an array of one or more @ref Math::Vector instances. Both vectors
time) and can store any arithmetic type. 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. For the most common
vector and matrix sizes there are specialized classes @ref Math::Matrix3 and Each subclass brings some specialization to its superclass. The
@ref Math::Matrix4, implementing various transformations in 2D and 3D and @ref Math::Vector2, @ref Math::Vector3 and @ref Math::Vector4 classes implement
@ref Math::Vector2, @ref Math::Vector3 and @ref Math::Vector4, implementing direct access to named components, @ref Math::Matrix adds determinant
direct access to named components. Functions of each class try to return the calculation or matrix inversion and @ref Math::Matrix3 / @ref Math::Matrix4
most specialized type known to make subsequent operations more convenient --- implement 2D and 3D transformations. Functions of each class return the most
columns of @ref Math::RectangularMatrix are returned as @ref Math::Vector, but specialized type known to make subsequent operations more convenient ---
when accessing columns of e.g. @ref Math::Matrix3, they are returned as 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. @ref Math::Vector3.
There are also even more specialized subclasses, e.g. @ref Math::Color3 and There are also even more specialized subclasses, e.g. @ref Math::Color3 and
@ref Math::Color4 for color handling and conversion. @ref Math::Color4 for color handling and conversion.
Commonly used types have convenience aliases in @ref Magnum namespace, so you Commonly used types have convenience aliases in the @ref Magnum namespace, so
can write e.g. @ref Vector3i instead of @ref Math::Vector3 "Math::Vector3<Int>". you can write e.g. @ref Vector3i instead of
See @ref types and @ref Magnum namespace documentation for more information. @ref Math::Vector3 "Math::Vector3<Int>". See @ref types and the @ref Magnum
namespace documentation for more information.
@section matrix-vector-construction Constructing matrices and vectors @section matrix-vector-construction Constructing matrices and vectors
The default constructors of @ref Math::RectangularMatrix and @ref Math::Vector (and The default constructors of @ref Math::RectangularMatrix and @ref Math::Vector
@ref Math::Vector2, @ref Math::Vector3, @ref Math::Vector4, @ref Math::Color3, (and @ref Math::Vector2, @ref Math::Vector3, @ref Math::Vector4,
@ref Math::Color4) create zero-filled objects. @ref Math::Matrix (and @ref Math::Color3, @ref Math::Color4) create zero-filled objects, equivalent
@ref Math::Matrix3, @ref Math::Matrix4) is by default constructed as an identity to using the @ref Math::ZeroInit tag. @ref Math::Matrix (and
matrix. @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 @snippet MagnumMath.cpp matrix-vector-construct
The most common and most efficient way to create a vector is to pass all values to The most common and most efficient way to create a vector is to pass all values
the constructor. A matrix is created by passing all the column vectors to the to the constructor. A matrix is created by passing all *column* vectors to the
constructor. These constructors check the number of passed arguments and errors constructor. The constructors check correct number of passed arguments at
are caught at compile time. compile time.
@snippet MagnumMath.cpp matrix-vector-construct-value @snippet MagnumMath.cpp matrix-vector-construct-value
You can specify all components of vectors or the diagonal of a square matrix You can specify all components of a vector or a matrix with a single value, or
with a single value or create a diagonal matrix from a vector: specify just values on the matrix diagonal:
@snippet MagnumMath.cpp matrix-vector-construct-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 @snippet MagnumMath.cpp matrix-vector-construct-axis
It is also possible to create matrices and vectors from a C-style array. The 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 function performs a simple type cast without copying anything, so it's possible
conveniently operate on the array itself: to conveniently operate on the array itself:
@snippet MagnumMath.cpp matrix-vector-construct-from @snippet MagnumMath.cpp matrix-vector-construct-from
@attention Note that, unlike a constructor, this function has no way to check @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 whether the array is long enough to contain all the elements, so use it
caution. with caution.
To make handling colors easier, their behavior is a bit different with a 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 richer feature set. Implicit construction of @ref Math::Color4 from just the
set the alpha to the max value (thus @cpp 1.0f @ce for @ref Color4 and @cpp 255 @ce RGB components will set the alpha to the max value (thus @cpp 1.0f @ce for
for @ref Color4ub): @ref Color4 and @cpp 255 @ce for @ref Color4ub):
@snippet MagnumMath.cpp matrix-vector-construct-color @snippet MagnumMath.cpp matrix-vector-construct-color
Similar to axes in vectors, you can create single color shades too, or create Similar to axes and scales in vectors, you can create single color shades too:
a RGB color from a HSV representation:
@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 Finally, the namespace @ref Math::Literals provides convenient
@link Literals::operator""_rgb() operator""_rgb() @endlink / @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 @section matrix-vector-component-access Accessing matrix and vector components
Column vectors of matrices and vector components can be accessed using square Column vectors of matrices and components of vectors can be accessed using
brackets: square brackets:
@snippet MagnumMath.cpp matrix-vector-access @snippet MagnumMath.cpp matrix-vector-access
Row vectors can be accessed too, but only for reading, and access is slower 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 @snippet MagnumMath.cpp matrix-vector-access-row
Fixed-size vector subclasses have functions for accessing named components 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 @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 are the @ref Math::gather()
For more involved operations with components there is the @ref Math::gather()
and @ref Math::scatter() functions: and @ref Math::scatter() functions:
@snippet MagnumMath.cpp matrix-vector-access-swizzle @snippet MagnumMath.cpp matrix-vector-access-swizzle
@section matrix-vector-conversion Converting between different underlying types @section matrix-vector-conversion Converting between different underlying types
All vector, matrix and other classes in @ref Math namespace can be All classes in @ref Math namespace can be constructed from an instance with a
constructed from an instance with a different underlying type (e.g. convert different underlying type (e.g. convert between integer and floating-point type
between integer and floating-point or betweeen @ref Float and @ref Double). or betweeen @ref Float, @ref Double and @ref Half). Unlike with plain C++ data
Unlike with plain C++ data types, the conversion is done via an *explicit* types, the conversion is *explicit*. That might sound inconvenient at first,
constructor. That might sound inconvenient, but performing the conversion but performing the conversion explicitly avoids common issues like precision
explicitly avoids common issues like precision loss (or, on the other hand, loss (or, on the other hand, expensive computation with unnecessarily high
expensive computation with unnecessarily high precision). precision).
To further emphasise the intent of conversion (so it doesn't look like an accident To further emphasise the intent of conversion (so it doesn't look like an
or a typo), you are encouraged to use @cpp auto b = Type{a} @ce instead of accident or a typo), you are encouraged to use @cpp auto b = Type{a} @ce
@cpp Type b{a} @ce. instead of @cpp Type b{a} @ce.
@snippet MagnumMath.cpp matrix-vector-convert @snippet MagnumMath.cpp matrix-vector-convert
For packing and unpacking use the @ref Math::pack() and @ref Math::unpack() For packing floats into integers and unpacking them back use the
functions: @ref Math::pack() and @ref Math::unpack() functions:
@snippet MagnumMath.cpp matrix-vector-convert-pack @snippet MagnumMath.cpp matrix-vector-convert-pack
See @ref matrix-vector-componentwise "below" for more information about other See below for more information about other available
available component-wise operations. @ref matrix-vector-componentwise "component-wise operations".
@section matrix-vector-operations Operations with matrices and vectors @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 @snippet MagnumMath.cpp matrix-vector-operations-multiply
When working with integral vectors (i.e. 24bit RGB values), it is often 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. desirable to multiply them with floating-point values but retain an integral
In Magnum, all multiplication/division operations involving integral vectors result. In Magnum, all multiplication/division operations involving integral
will return integers within the result, you need to convert both arguments to the same vectors will return an integer result, you need to convert both arguments to
floating-point type to have floating-point result. the same floating-point type to have a floating-point result.
@snippet MagnumMath.cpp matrix-vector-operations-integer @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 @snippet MagnumMath.cpp matrix-vector-operations-matrix
You can also multiply (properly sized) vectors with matrices. These operations 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 @snippet MagnumMath.cpp matrix-vector-operations-multiply-matrix
@section matrix-vector-componentwise Component-wise and inter-vector operations @section matrix-vector-componentwise Component-wise and inter-vector operations
As shown above, vectors can be added and multiplied component-wise using the 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()" @cpp + @ce or @cpp * @ce operator. For a sum or product of components *inside*
and @ref Math::Vector::product() "product()" for sum or product of components a vector you can use @ref Math::Vector::sum() "sum()" and
in one vector: @ref Math::Vector::product() "product()" instead:
@snippet MagnumMath.cpp matrix-vector-operations-componentwise @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 @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: @ref Math::BoolVector class:
@snippet MagnumMath.cpp matrix-vector-operations-compare @snippet MagnumMath.cpp matrix-vector-operations-compare
There are also function for component-wise rounding, sign operations, square 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 @snippet MagnumMath.cpp matrix-vector-operations-functions
Component-wise functions are implemented only for vectors and not for matrices 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 to keep the math library in a sane and maintainable size. Instead, you can
reinterpret the matrix as vector and do the operation on it (and vice versa): 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 @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 @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. 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 @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 For consistency with GLSL, Magnum stores matrices as column-major (the vectors
also as column-major (the vectors are the columns). This naturally has some are columns). This naturally has some implications and it may differ from what
implications and it may differ from what is common in mathematics: you're used to from linear algebra or other graphics toolkits:
<ul><li> <ul><li>
Order of template arguments in specification of @ref Math::RectangularMatrix 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 @snippet MagnumMath.cpp matrix-vector-column-major-construct
</li><li> </li><li>
Element access order is also column-major, thus the bracket operator Element access order is also column-major, thus the bracket operator
accesses columns. The returned vector also has its own bracket operator, which accesses columns. The returned vector also has its own bracket operator,
then indexes rows. which then indexes rows.
@snippet MagnumMath.cpp matrix-vector-column-major-access @snippet MagnumMath.cpp matrix-vector-column-major-access
</li><li> </li><li>

79
doc/snippets/MagnumMath.cpp

@ -49,16 +49,18 @@ using namespace Magnum::Math::Literals;
int main() { int main() {
{ {
/* [matrix-vector-construct] */ /* [matrix-vector-construct] */
Matrix2x3 a; // zero-filled Matrix2x3 a; // zero-filled
Vector3i b; // zero-filled Vector3i b; // zero-filled
Matrix3 identity; // diagonal set to 1 Matrix3 c; // diagonal set to 1.0f
Matrix3 zero{Math::ZeroInit}; // zero-filled Matrix3 d{Math::IdentityInit}; // diagonal set to 1.0f
Matrix3 e{Math::ZeroInit}; // zero-filled
/* [matrix-vector-construct] */ /* [matrix-vector-construct] */
static_cast<void>(a); static_cast<void>(a);
static_cast<void>(b); static_cast<void>(b);
static_cast<void>(identity); static_cast<void>(c);
static_cast<void>(zero); static_cast<void>(d);
static_cast<void>(e);
} }
{ {
@ -76,7 +78,7 @@ static_cast<void>(mat);
{ {
/* [matrix-vector-construct-diagonal] */ /* [matrix-vector-construct-diagonal] */
Matrix3 diag{Math::IdentityInit, 2.0f}; // diagonal is 2.0f, zeros elsewhere 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}); auto diag2 = Matrix3::fromDiagonal({3.0f, 2.0f, 1.0f});
/* [matrix-vector-construct-diagonal] */ /* [matrix-vector-construct-diagonal] */
static_cast<void>(diag); static_cast<void>(diag);
@ -105,29 +107,38 @@ Math::Matrix2x3<Int>::from(mat) *= 2; // { 4, 8, 12, 2, 6, 10 }
{ {
/* [matrix-vector-construct-color] */ /* [matrix-vector-construct-color] */
Color4 a = Color3{0.2f, 0.7f, 0.5f}; // {0.2f, 0.7f, 0.5f, 1.0f} 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} Color4ub b = Color3ub{0x33, 0xb2, 0x7f}; // {0x33, 0xb2, 0x7f, 0xff}
/* [matrix-vector-construct-color] */ /* [matrix-vector-construct-color] */
static_cast<void>(a); static_cast<void>(a);
static_cast<void>(b); static_cast<void>(b);
} }
{ {
/* [matrix-vector-construct-color-hue] */ /* [matrix-vector-construct-color-axis] */
auto green = Color3::green(); // {0.0f, 1.0f, 0.0f} 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 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-axis] */
/* [matrix-vector-construct-color-hue] */
static_cast<void>(green); static_cast<void>(green);
static_cast<void>(cyan); static_cast<void>(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<void>(fadedRed); static_cast<void>(fadedRed);
static_cast<void>(linear);
} }
{ {
/* [matrix-vector-construct-color-literal] */ /* [matrix-vector-construct-color-literal] */
Color3ub a = 0x33b27f_rgb; // {0x33, 0xb2, 0x7f} Color3ub a = 0x33b27f_rgb; // {0x33, 0xb2, 0x7f}
Color4 b = 0x33b27fcc_rgbaf; // {0.2f, 0.7f, 0.5f, 0.8f} Color4 b = 0x33b27fcc_rgbaf; // {0.2f, 0.7f, 0.5f, 0.8f}
Color4 c = 0x33b27fcc_srgbaf; // {0.0331048f, 0.445201f, 0.212231f, 0.8f} Color4 c = 0x33b27fcc_srgbaf; // {0.0331048f, 0.445201f, 0.212231f, 0.8f}
/* [matrix-vector-construct-color-literal] */ /* [matrix-vector-construct-color-literal] */
static_cast<void>(a); static_cast<void>(a);
static_cast<void>(b); static_cast<void>(b);
@ -137,15 +148,15 @@ static_cast<void>(c);
{ {
/* [matrix-vector-access] */ /* [matrix-vector-access] */
Matrix3x2 a; Matrix3x2 a;
a[2] /= 2.0f; // third column (column major indexing, see explanation below) a[2] /= 2.0f; // third column
a[0][1] = 5.3f; // first column, second element a[0][1] = 5.3f; // first column, second element
Vector3i b; Vector3i b;
b[1] = 1; // second element b[1] = 1; // second element
/* [matrix-vector-access] */ /* [matrix-vector-access] */
/* [matrix-vector-access-row] */ /* [matrix-vector-access-row] */
Vector3 c = a.row(1); // second row Vector3 c = a.row(1); // second row
/* [matrix-vector-access-row] */ /* [matrix-vector-access-row] */
static_cast<void>(c); static_cast<void>(c);
} }
@ -165,13 +176,13 @@ static_cast<void>(x);
{ {
/* [matrix-vector-access-swizzle] */ /* [matrix-vector-access-swizzle] */
Vector4i orig{-1, 2, 3, 4}; 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); 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}; Vector4 vec{1.5f, 3.0f, 0.1f, 1.1f};
Vector2 coords{5.0f, -2.0f}; 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] */ /* [matrix-vector-access-swizzle] */
static_cast<void>(bgra); static_cast<void>(bgra);
@ -204,7 +215,7 @@ static_cast<void>(d);
{ {
/* [matrix-vector-operations-vector] */ /* [matrix-vector-operations-vector] */
Vector3 a{1.0f, 2.0f, 3.0f}; 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} Vector3 c = 1.0f/a; // {1.0f, 0.5f, 0.333f}
/* [matrix-vector-operations-vector] */ /* [matrix-vector-operations-vector] */
static_cast<void>(b); static_cast<void>(b);
@ -272,8 +283,8 @@ static_cast<void>(e);
{ {
/* [matrix-vector-operations-componentwise] */ /* [matrix-vector-operations-componentwise] */
Float a = Vector3{1.5f, 0.3f, 8.0f}.sum(); // 8.8f Float a = Vector3{1.5f, 0.3f, 8.0f}.sum(); // 9.8f
Int b = Vector3i{32, -5, 7}.product(); // 1120 Int b = Vector3i{32, -5, 7}.product(); // -1120
/* [matrix-vector-operations-componentwise] */ /* [matrix-vector-operations-componentwise] */
static_cast<void>(a); static_cast<void>(a);
static_cast<void>(b); static_cast<void>(b);
@ -302,9 +313,9 @@ static_cast<void>(allLarger);
{ {
/* [matrix-vector-operations-functions] */ /* [matrix-vector-operations-functions] */
Vector3 a{5.5f, -0.3f, 75.0f}; Vector3 a{5.5f, -0.3f, 75.1f};
Vector3 b = Math::round(a); // {5.0f, 0.0f, 75.0f} Vector3 b = Math::round(a); // {6.0f, 0.0f, 75.0f}
Vector3 c = Math::abs(a); // {5.5f, -0.3f, 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} Vector3 d = Math::clamp(a, -0.2f, 55.0f); // {5.5f, -0.2f, 55.0f}
/* [matrix-vector-operations-functions] */ /* [matrix-vector-operations-functions] */
static_cast<void>(b); static_cast<void>(b);
@ -336,6 +347,14 @@ static_cast<void>(b);
static_cast<void>(c); static_cast<void>(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] */ /* [matrix-vector-column-major-template] */
Math::RectangularMatrix<2, 5, Int> mat; // two columns, five rows Math::RectangularMatrix<2, 5, Int> mat; // two columns, five rows

65
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 arithmetic types to ensure portability, maintain consistency and reduce
confusion. E.g., the @ref Int typedef is guaranteed to *always* be 32-bit and 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 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. refer to the same type.
| Magnum type | Size | Equivalent GLSL 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 Scalar types with a GLSL equivalent are guaranteed to have exactly the same
binary representation. Consequently, matrix and vector classes also have the binary representation. Consequently, matrix and vector classes also have the
same binary representation as corresponding array of numeric values without any same binary representation as corresponding array of numeric values without any
additional data or padding (e.g. @cpp sizeof(Vector3i) == sizeof(Int[3]) @ce), additional data or padding (e.g. @cpp sizeof(Vector3i) == sizeof(Int[3]) @ce).
all matrices are stored in column-major order. All matrices are stored in column-major order.
This means that all scalar, matrix and vector types can be used directly for 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 filling GPU buffers and textures without any need for data extraction or
conversion. For convenience all vector and matrix classes provide conversion. For convenience all vector and matrix classes provide a
@ref Math::RectangularMatrix::data() "data()" function, which returns pointer @ref Math::RectangularMatrix::data() "data()" function, which returns a pointer
to the internal data array. 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 @section types-special Special types
Magnum has special type for strongly-typed representation of angles, namely Magnum has a 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 the @ref Deg and @ref Rad classes (or @ref Degd / @ref Degh and @ref Radd /
as underlying type). Their only purpose is to avoid common degree-vs-radian @ref Radh with @ref Double / @ref Half as underlying type). Their purpose is to
bugs (i.e. entering degree value where radians should be) and make the avoid common degree-vs-radian bugs (i.e. entering a degree value where radians
conversion between these two representations easier. They are just a tiny should be and vice versa) and make the conversion between these two
@cpp constexpr @ce wrapper around the native type and they support all representations easier. They are just a tiny @cpp constexpr @ce wrapper around
meaningful numeric operations, so using them won't have any performance or the native type and they support all meaningful numeric operations. The wrapper
usability impact in practice. 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 These classes are *not* implicitly constructible or convertible from/to
@ref Float or @ref Double, you have to either construct/convert them explicitly @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 @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 @section types-other Other types
Other types, which don't have their GLSL equivalent, are: 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. underlying structure or converting them to types supported by GLSL (e.g.
quaternion to matrix). quaternion to matrix).
For your convenience, there is also alias for class with often used constants For your convenience, there is also a structure with often used constants
--- @ref Constants or @ref Constantsd. --- @ref Constants, or @ref Constantsd for the double-precision variants.
@section types-initialization Initialization @section types-initialization Initialization
Vectors, general matrices and range types are by default zero-initialized, Vectors, general matrices and range types are by default zero-initialized,
transformation types (square matrices, (dual) complex numbers and quaternions) transformation types (square matrices, (dual) complex numbers and quaternions)
are set to identity transformation. It is possible to initialize the instances 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: explicit:
- @ref Math::ZeroInit zero-initializes the contents (works for all types). - @ref Math::ZeroInit zero-initializes the contents (works for all types).
- @ref Math::IdentityInit initializes the contents to identity transformation - @ref Math::IdentityInit initializes the contents to identity transformation
(works only for transformation types, where it is also the default). (works only for transformation types, where it is also the default).
- @ref Math::NoInit leaves the contents uninitialized (useful if you will - @ref NoInit leaves the contents uninitialized (useful if you will overwrite
overwrite the contents anyway, works for all types). the contents anyway, works for all types).
Example: Example:

12
src/Magnum/Math/Color.h

@ -433,7 +433,7 @@ template<class T> class Color3: public Vector3<T> {
} }
/** /**
* @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 * @param xyz Color in CIE XYZ color space
* *
* Applies transformation matrix, returning the input in linear * Applies transformation matrix, returning the input in linear
@ -596,7 +596,7 @@ template<class T> class Color3: public Vector3<T> {
} }
/** /**
* @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° * Assuming the color is in linear RGB with D65 illuminant and 2°
* standard colorimetric observer, applies transformation matrix, * standard colorimetric observer, applies transformation matrix,
@ -850,7 +850,7 @@ class Color4: public Vector4<T> {
} }
/** /**
* @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 xyz Color in CIE XYZ color space
* @param a Alpha value, defaults to @cpp 1.0 @ce for * @param a Alpha value, defaults to @cpp 1.0 @ce for
* floating-point types and maximum positive value for integral * floating-point types and maximum positive value for integral
@ -1008,7 +1008,7 @@ class Color4: public Vector4<T> {
} }
/** /**
* @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, * Assuming the color is in linear RGB, applies transformation matrix,
* returning the color in CIE XYZ color space. The alpha channel is not * returning the color in CIE XYZ color space. The alpha channel is not
@ -1037,7 +1037,7 @@ class Color4: public Vector4<T> {
}; };
/** @relatesalso Color3 /** @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[ @f[
\begin{array}{rcl} \begin{array}{rcl}
@ -1052,7 +1052,7 @@ template<class T> inline Vector3<T> xyYToXyz(const Vector3<T>& xyY) {
} }
/** @relatesalso Color3 /** @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[ @f[
\begin{array}{rcl} \begin{array}{rcl}

13
src/Magnum/Math/Half.h

@ -49,12 +49,13 @@ MAGNUM_EXPORT Float unpackHalf(UnsignedShort value);
/** /**
@brief Half-precision float literal @brief Half-precision float literal
The purpose of this class is just to make specifying and printing of half-float Represents a floating-point value in the [`binary16` format](https://en.wikipedia.org/wiki/Half-precision_floating-point_format).
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 The sole purpose of this type is to make creation, conversion and visualization
faster to just use regular single-precision @ref Magnum::Float "Float". See of half-float values easier. By design it doesn't support any arithmetic
[Wikipedia](https://en.wikipedia.org/wiki/Half-precision_floating-point_format) operations as not all CPU architecture have native support for half-floats and
for more information about half floats. 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", The class provides explicit conversion from and to @ref Magnum::Float "Float",
equality comparison with correct treatment of NaN values, promotion and equality comparison with correct treatment of NaN values, promotion and

Loading…
Cancel
Save