From 2893d12ece8779d2bf010eab919c92a2b82b2378 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 2 Sep 2013 22:44:18 +0200 Subject: [PATCH] Updated matrix/vector documentation. --- doc/matrix-vector.dox | 180 +++++++++++++++++++++++++++++------------- 1 file changed, 126 insertions(+), 54 deletions(-) diff --git a/doc/matrix-vector.dox b/doc/matrix-vector.dox index 82ab2d98b..c5703196a 100644 --- a/doc/matrix-vector.dox +++ b/doc/matrix-vector.dox @@ -22,7 +22,7 @@ DEALINGS IN THE SOFTWARE. */ -namespace Magnum { namespace Math { +namespace Magnum { /** @page matrix-vector Operations with matrices and vectors @brief Introduction to essential classes of the graphics pipeline. @@ -36,68 +36,79 @@ easier. @section matrix-vector-hierarchy Matrix and vector classes -%Magnum has three main matrix and vector classes: RectangularMatrix, (square) -Matrix and Vector. To achieve greatest code reuse, %Matrix is internally -square %RectangularMatrix and %RectangularMatrix is internally array of one or -more %Vector instances. Both vectors and matrices can have arbitrary size -(known at compile time) and can store any arithmetic type. +%Magnum has three main matrix and vector classes: @ref Math::RectangularMatrix, +(square) @ref Math::Matrix and @ref Math::Vector. To achieve greatest code +reuse, %Matrix is internally square %RectangularMatrix and %RectangularMatrix +is internally array of one or more %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 and for most common -vector and matrix sizes there are specialized classes Matrix3 and Matrix4, -implementing various transformation in 2D and 3D, Vector2, Vector3 and 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 %RectangularMatrix are returned as %Vector, but when -accessing columns of e.g. %Matrix3, they are returned as %Vector3. +vector and matrix sizes there are specialized classes @ref Math::Matrix3 and +@ref Math::Matrix4, implementing various transformations in 2D and 3D, +@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 %RectangularMatrix are returned as %Vector, but when accessing +columns of e.g. %Matrix3, they are returned as %Vector3. -There are also even more specialized subclasses, e.g. Color3 and Color4 for -color handling and conversion. +There are also even more specialized subclasses, e.g. @ref Color3 and +@ref Color4 for color handling and conversion. + +Commonly used types have convenience aliases in @ref Magnum namespace, so you +can write e.g. `%Vector3i` instead of `%Math::Vector3`. See @ref types and +namespace documentation for more information. @section matrix-vector-construction Constructing matrices and vectors -Default constructors of RectangularMatrix and Vector (and Vector2, Vector3, -Vector4, Color3) create zero-filled objects. Matrix (and Matrix3, Matrix4) is -by default constructed as identity matrix. Color4 has alpha value set to opaque. +Default constructors of @ref Math::RectangularMatrix and @ref Math::Vector (and +@ref Math::Vector2, @ref Math::Vector3, @ref Math::Vector4, @ref Color3) create +zero-filled objects. @ref Math::Matrix (and @ref Math::Matrix3, @ref Math::Matrix4) +is by default constructed as identity matrix. @ref Color4 has alpha value set +to opaque. @code -RectangularMatrix<2, 3, Int> a; // zero-filled -Vector<3, Int> b; // zero-filled +Matrix2x3 a; // zero-filled +Vector3i b; // zero-filled -Matrix<3, Int> identity; // diagonal set to 1 -Matrix<3, Int> zero(Matrix<3, Int>::Zero); // zero-filled +Matrix3 identity; // diagonal set to 1 +Matrix3 zero(Matrix::Zero); // zero-filled -Color4 black1; // {0.0f, 0.0f, 0.0f, 1.0f} -Color4 black2; // {0, 0, 0, 255} +Color4 black1; // {0.0f, 0.0f, 0.0f, 1.0f} +BasicColor4 black2; // {0, 0, 0, 255} @endcode Most common and most efficient way to create vector is to pass all values to constructor, matrix is created by passing all column vectors to the constructor. @code -Vector3 vec(0, 1, 2); +Vector3i vec(0, 1, 2); -Matrix3 mat({0, 1, 2}, - {3, 4, 5}, - {6, 7, 8}); +Matrix3 mat({0.0f, 1.9f, 2.2f}, + {3.5f, 4.0f, 5.1f}, + {6.0f, 7.3f, 8.0f}); @endcode All constructors check number of passed arguments and the errors are catched at compile time. You can specify all components of vector or whole diagonal of square matrix at -once: +once or you can create diagonal matrix from vector: @code -Matrix3 diag(Matrix3::Identity, 2); // diagonal set to 2, zeros elsewhere -Vector3 fill(10); // {10, 10, 10} +Matrix3 diag(Matrix3::Identity, 2.0f); // diagonal set to 2.0f, zeros elsewhere +Vector3i fill(10); // {10, 10, 10} +auto diag2 = Matrix3::fromDiagonal({3.0f, 2.0f, 1.0f}); @endcode -It is possible to create matrices from other matrices and vectors with the -same row count; vectors from vector and scalar: +It is possible to create matrices from other matrices and vectors with the same +row count; vectors from vector and scalar: @code -RectangularMatrix<2, 3, Int> a; -Vector3 b, c; -Matrix3 mat(a, b); -Vector<8, Int> vec(1, b, 2, c); +Math::RectangularMatrix<2, 3, Int> a; +Math::Vector<3, Int> b, c; +Math::Matrix3 mat(a, b); +Math::Vector<8, Int> vec(1, b, 2, c); @endcode +@todo Implement this ^ already. + It is also possible to create them from an C-style array. The function does simple type cast without any copying, so it's possible to conveniently operate on the array itself: @@ -111,8 +122,8 @@ array is long enough to contain all elements, so use with caution. You can also *explicitly* convert between data types: @code -Vector4 floating(1.3f, 2.7f, -15.0f, 7.0f); -Vector4 integral(floating); // {1, 2, -15, 7} +Vector4 floating(1.3f, 2.7f, -15.0f, 7.0f); +auto integral = Vector4i(floating); // {1, 2, -15, 7} @endcode @section matrix-vector-component-access Accessing matrix and vector components @@ -121,37 +132,98 @@ Column vectors of matrices and vector components can be accessed using square brackets, there is also round bracket operator for accessing matrix components directly: @code -RectangularMatrix<3, 2, Int> a; -a[2] /= 2; // third column (column major indexing, see explanation below) -a[0][1] = 5; // first column, second element +Matrix3x2 a; +a[2] /= 2.0f; // third column (column major indexing, see explanation below) +a[0][1] = 5.3f; // first column, second element -Vector<3, Int> b; +Vector3i b; b[1] = 1; // second element @endcode Row vectors can be accessed too, but only for reading, and the access is slower due to the way the matrix is stored (see explanation below): @code -Vector<2, Int> c = a.row(2); // third row +Vector2i c = a.row(2); // third row @endcode Fixed-size vector subclasses have functions for accessing named components and subparts: @code -Vector4 a; +Vector4i a; Int x = a.x(); a.y() += 5; -Vector3 xyz = a.xyz(); +Vector3i xyz = a.xyz(); xyz.xy() *= 5; @endcode Color3 and Color4 name their components `rgba` instead of `xyzw`. -For more involved operations with components there is the swizzle() function: +For more involved operations with components there is the @ref swizzle() +function: +@code +Vector4i original(-1, 2, 3, 4); +Vector4i bgra = swizzle<'b', 'g', 'r', 'a'>(original); // { 3, 2, -1, 4 } +Math::Vector<6, Int> w10xyz = swizzle<'w', '1', '0', 'x', 'y', 'z'>(original); // { 4, 1, 0, -1, 2, 3 } +@endcode + +@section matrix-vector-operations Operations with matrices and vectors + +Vectors can be added, subtracted, negated and multiplied or divided with +scalars, as is common in mathematics, Magnum also adds the ability to divide +scalar with vector: +@code +Vector3 a(1.0f, 2.0f, 3.0f); +Vector3 b = a*5.0f - Vector3(3.0f, -0.5f, -7.5f); // b == {5.0f, 9.5f, 7.5f} +Vector3 c = 1.0f/a; // c == {1.0f, 0.5f, 0.333f} +@endcode + +As in GLSL, vectors can be also multiplied or divided component-wise: +@code +Vector3 a(1.0f, 2.0f, 3.0f); +Vector3 b = a*Vector3(-0.5f, 2.0f, -7.0f); // b == {-0.5f, 4.0f, -21.0f} +@endcode + +When working with integral vectors (i.e. 24bit RGB values), it is often +desirable to multiply them with floating-point values but with integral result. +In %Magnum all mulitplication/division operations involving integral vectors +will have integral result, you need to convert both arguments to the same +floating-point type to have floating-point result. @code -Vector<4, Int> original(-1, 2, 3, 4); -Vector<4, Int> bgra = swizzle<'b', 'g', 'r', 'a'>(original); // { 3, 2, -1, 4 } -Vector<6, Int> w10xyz = swizzle<'w', '1', '0', 'x', 'y', 'z'>(original); // { 4, 1, 0, -1, 2, 3 } +BasicColor3 color(80, 116, 34); +BasicColor3 lighter = color*1.5f; // lighter = {120, 174, 51} + +Vector3i a(4, 18, -90); +Vector3 multiplier(2.2f, 0.25f, 0.1f); +Vector3i b = a*multiplier; // b == {8, 4, -9} +Vector3 c = Vector3(a)*multiplier; // c == {8.0f, 4.5f, -9.0f} +@endcode + +You can use also all bitwise operations on integral vectors: +@code +Vector2i size(256, 256); +Vector2i mipLevel3Size = size >> 3; // == {32, 32} +@endcode + +Matrices can be added, subtracted and multiplied with matrix multiplication. +@code +Matrix3x2 a; +Matrix3x2 b; +Matrix3x2 c = a + (-b); + +Matrix2x3 d; +Matrix2x2 e = d*b; +Matrix3x3 f = b*d; +@endcode + +You can also multiply (properly sized) vectors with matrices. These operations +are just convenience shortcuts for multiplying with single-column matrices: +@code +Matrix3x4 a; +Vector3 b; +Vector4 c = a*b; + +Math::RectangularMatrix<4, 1, Float> d; +Matrix4x3 e = b*d; @endcode @section matrix-vector-column-major Matrices are column-major and vectors are columns @@ -163,21 +235,21 @@ implications and it may differ from what is common in mathematics: - Order of template arguments in specification of RectangularMatrix is also column-major: @code -RectangularMatrix<2, 3, Int> mat; // two columns, three rows +Math::RectangularMatrix<2, 3, Int> mat; // two columns, three rows @endcode - Order of components in matrix constructors is also column-major, further emphasized by requirement that you have to pass directly column vectors: @code -Matrix3 mat({0, 1, 2}, - {3, 4, 5}, - {6, 7, 8}); // first column is {0, 1, 2} +Math::Matrix3 mat({0, 1, 2}, + {3, 4, 5}, + {6, 7, 8}); // first column is {0, 1, 2} @endcode - Element accessing order is also column-major, thus the bracket operator is accessing columns. Returned vector has also its own bracket operator, which is then indexing rows. @code mat[0] *= 2; // first column -mat[2][0] = 5; // first element of first column +mat[2][0] = 5; // first element of third column @endcode - Various algorithms which commonly operate on matrix rows (such as @ref Algorithms::gaussJordanInPlace() "Gauss-Jordan elimination") have faster