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: