Browse Source

Doc: brief introduction to matrix and vector classes.

DDD - documentation driven development. Not all advertised features are
available right now, but they will come.
vectorfields
Vladimír Vondruš 14 years ago
parent
commit
6a4b68410c
  1. 5
      doc/mainpage.dox
  2. 181
      doc/matrix-vector.dox
  3. 3
      doc/namespaces.dox
  4. 6
      src/Math/Matrix.h
  5. 5
      src/Math/Matrix3.h
  6. 5
      src/Math/Matrix4.h
  7. 4
      src/Math/RectangularMatrix.h
  8. 3
      src/Math/Vector.h
  9. 2
      src/Math/Vector2.h
  10. 2
      src/Math/Vector3.h
  11. 2
      src/Math/Vector4.h
  12. 6
      src/Swizzle.h

5
doc/mainpage.dox

@ -4,8 +4,9 @@ namespace Magnum {
%Magnum is 3D graphics engine written in C++11 and OpenGL 3 Core Profile.
Features:
- Easy-to-use templated @ref Math "mathematical library" for matrix/vector
calculations and @ref Math::Geometry "geometry".
- Easy-to-use templated @ref Math "mathematical library" for
@ref matrix-vector "matrix/vector calculations" and
@ref Math::Geometry "geometry".
- Classes wrapping OpenGL objects and simplifying their usage -
@ref AbstractShaderProgram "shaders", @ref Buffer "buffers",
@ref Mesh "meshes" and @ref AbstractTexture "textures". Access to

181
doc/matrix-vector.dox

@ -0,0 +1,181 @@
namespace Magnum { namespace Math {
/** @page matrix-vector Operations with matrices and vectors
@brief Introduction to essential classes of the graphics pipeline.
@tableofcontents
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. This
page will overview their usage and introduce some tricks to make your life
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 %Vector is internally one-column
%RectangularMatrix. Both vectors and matrices can have arbitrary size (known
at compile time) and can store any meaningful 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.
There are also even more specialized subclasses - Point2D, Point3D for
creating points with homogeneous coordinates and Color3, Color4 for color
handling and conversion.
@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. Point2D and Point3D have
homogeneous component set to one, Color4 has alpha value set to opaque.
@code
RectangularMatrix<2, 3, int> a; // zero-filled
Vector<3, int> b; // zero-filled
Matrix<3, int> identity; // diagonal set to 1
Matrix<3, int> zero(Matrix<3, int>::Zero); // zero-filled
Point2D<int> c; // {0, 0, 1}
Point3D<int> d; // {0, 0, 0, 1}
Color4<float> black1; // {0.0f, 0.0f, 0.0f, 1.0f}
Color4<unsigned char> black2; // {0, 0, 0, 255}
@endcode
Most common and most efficient way to create matrix or vector is to pass
values of all components to the constructor.
@code
Matrix3<int> mat(0, 1, 2,
3, 4, 5,
6, 7, 8); // column-major (see explanation why below)
Vector3<int> vec(0, 1, 2);
@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:
@code
Matrix3<int> diag(Matrix3<int>::Identity, 2); // diagonal set to 2, zeros elsewhere
Vector3<int> fill(10); // {10, 10, 10}
@endcode
Vectors are commonly used to specify various axes and scaling coefficients in
transformations, you can use convenience functions instead of typing out all
other elements:
@code
Matrix4::rotation(deg(5.0f), Vector3::xAxis()); // {1.0f, 0.0f, 0.0f}
Matrix3::translation(Vector2::yAxis(2.0f)); // {0.0f, 2.0f}
Matrix4::scaling(Vector3::zScale(-10.0f)); // {1.0f, 1.0f, -10.0f}
@endcode
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<int> b, c;
Matrix3<int> mat = Matrix3<int>::from(b, a, c);
Vector<8, int> vec = Vector<8, int>::from(1, b, 2, c);
@endcode
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:
@code
int[] mat = { 2, 4, 6,
1, 3, 5 };
RectangularMatrix<2, 3, int>::from(mat) *= 2; // mat == { 4, 8, 12, 2, 6, 10 }
@endcode
Note that unlike constructors, this function has no way to check whether the
array is long enough to contain all elements, so use with caution.
You can also convert between data types:
@code
Vector4<float> floating(1.3f, 2.7f, -15.0f, 7.0f);
Vector4<int> integral(Vector4<int>::from(floating)); // {1, 2, -15, 7}
@endcode
@section matrix-vector-component-access Accessing matrix and vector components
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
a(0, 1) += 3; // first column, second element (preferred)
Vector<3, int> b;
b[1] = 1; // second element
@endcode
For accessing matrix element prefer round bracket operator, as it is possibly
faster than the double square brackets (but never slower) and isn't prone to
compiler mis-optimizations.
Fixed-size vector subclasses have functions for accessing named components
and subparts:
@code
Vector4<int> a;
int x = a.x();
a.y() += 5;
Vector3<int> xyz = a.xyz();
xyz.xy() *= 5;
@endcode
Color3 and Color4 name their components `rgba` instead of `xyzw`.
For more involved operations with components there are two swizzle() functions,
they have the same features, but one is guaranteed to do most of the work at
compile-time, while the second has more convenient syntax:
@code
Vector4<int> original(1, 2, 3, 4);
Vector4<int> bgra = swizzle<'b', 'g', 'r', 'a'>(original); // { 3, 2, 1, 4 }
Vector<6, int> a10rgb = swizzle(original, "a10rgb"); // { 4, 1, 0, 1, 2, 3 }
@endcode
@section matrix-vector-column-major Matrices are column-major and vectors are columns
OpenGL matrices are column-major, thus it is reasonable to have matrices in
%Magnum also column major (and vectors as columns). This has naturally some
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
@endcode
- Order of components in matrix constructors is also column-major, so the
elements passed in constructor doesn't need to be reordered internally
before putting them into data array:
@code
Matrix3<int> mat(0, 1, 2,
3, 4, 5,
6, 7, 8); // first column is {0, 1, 2}
@endcode
- Element accessing order is also column-major. It costs virtually no time to
return reference to portion of data array as column vector, thus the bracket
operator is accessing columns. Returned vector has also its own bracket
operator, which is indexing rows. To avoid confusion, first parameter of
round bracket operator is thus also column index.
@code
mat[0] *= 2; // first column
mat[2][0] = 5; // first element of first column vector
mat(2, 0) += 3; // first element of first column
@endcode
- Various algorithms which commonly operate on matrix rows (such as
@ref Algorithms::GaussJordan "Gauss-Jordan elimination") have faster
alternatives which operate on columns. It's then up to user decision to
operate with transposed matrices or use the slower non-transposed
alternative of the algorithm.
*/
}}

3
doc/namespaces.dox

@ -25,7 +25,8 @@ Base classes for creating OpenGL contexts with various toolkits.
/** @namespace Magnum::Math
@brief %Math library
Template classes for matrix and vector calculations.
Template classes for matrix and vector calculations. See @ref matrix-vector
for brief introduction.
*/
/** @dir Math/Algorithms

6
src/Math/Matrix.h

@ -32,6 +32,9 @@ namespace Implementation {
/**
@brief Square matrix
@tparam s %Matrix size
@tparam T Data type
See @ref matrix-vector for brief introduction.
@configurationvalueref{Magnum::Math::Matrix}
@todo @c PERFORMANCE - loop unrolling for Matrix<3, T> and Matrix<4, T>
@ -228,7 +231,6 @@ namespace Implementation {
template<size_t size, class T> class MatrixDeterminant {
public:
/** @brief Functor */
T operator()(const Matrix<size, T>& m) {
T out(0);
@ -241,7 +243,6 @@ template<size_t size, class T> class MatrixDeterminant {
template<class T> class MatrixDeterminant<2, T> {
public:
/** @brief Functor */
inline constexpr T operator()(const Matrix<2, T>& m) {
return m(0, 0)*m(1, 1) - m(1, 0)*m(0, 1);
}
@ -249,7 +250,6 @@ template<class T> class MatrixDeterminant<2, T> {
template<class T> class MatrixDeterminant<1, T> {
public:
/** @brief Functor */
inline constexpr T operator()(const Matrix<1, T>& m) {
return m(0, 0);
}

5
src/Math/Matrix3.h

@ -26,9 +26,10 @@ namespace Magnum { namespace Math {
/**
@brief 3x3 matrix
@tparam T Data type
Provides functions for transformations in 2D. See also Matrix4 for 3D
transformations.
Provides functions for transformations in 2D. See Matrix4 for 3D
transformations. See also @ref matrix-vector for brief introduction.
@configurationvalueref{Magnum::Math::Matrix3}
*/
template<class T> class Matrix3: public Matrix<3, T> {

5
src/Math/Matrix4.h

@ -26,9 +26,10 @@ namespace Magnum { namespace Math {
/**
@brief 4x4 matrix
@tparam T Data type
Provides functions for transformations in 3D. See also Matrix3 for 2D
transformations.
Provides functions for transformations in 3D. See Matrix3 for 2D
transformations. See also @ref matrix-vector for brief introduction.
@configurationvalueref{Magnum::Math::Matrix4}
@todo Shearing
@todo Reflection

4
src/Math/RectangularMatrix.h

@ -48,8 +48,10 @@ template<size_t size, class T> class Vector;
@brief Rectangular matrix
@tparam c Column count
@tparam r Row count
@tparam T Data type
See also Matrix (square) and Vector.
See @ref matrix-vector for brief introduction. See also Matrix (square) and
Vector.
*/
template<size_t c, size_t r, class T> class RectangularMatrix {
static_assert(c != 0 && r != 0, "Matrix cannot have zero elements");

3
src/Math/Vector.h

@ -36,7 +36,10 @@ namespace Implementation {
/**
@brief %Vector
@tparam s %Vector size
@tparam T Data type
See @ref matrix-vector for brief introduction.
@configurationvalueref{Magnum::Math::Vector}
@todo Constexprize all for loops
*/

2
src/Math/Vector2.h

@ -25,7 +25,9 @@ namespace Magnum { namespace Math {
/**
@brief Two-component vector
@tparam T Data type
See @ref matrix-vector for brief introduction.
@configurationvalueref{Magnum::Math::Vector2}
*/
template<class T> class Vector2: public Vector<2, T> {

2
src/Math/Vector3.h

@ -25,7 +25,9 @@ namespace Magnum { namespace Math {
/**
@brief Three-component vector
@tparam T Data type
See @ref matrix-vector for brief introduction.
@configurationvalueref{Magnum::Math::Vector3}
*/
template<class T> class Vector3: public Vector<3, T> {

2
src/Math/Vector4.h

@ -25,7 +25,9 @@ namespace Magnum { namespace Math {
/**
@brief Four-component vector
@tparam T Data type
See @ref matrix-vector for brief introduction.
@configurationvalueref{Magnum::Math::Vector4}
*/
template<class T> class Vector4: public Vector<4, T> {

6
src/Swizzle.h

@ -97,7 +97,8 @@ swizzle(const T&, const char(&)[newSize]), but the evaluation of
the swizzling operation is guaranteed to be always done at compile time
instead of at runtime.
@see Vector4::xyz(), Vector4::rgb(), Vector4::xy(), Vector3::xy()
@see @ref matrix-vector-component-access, Vector4::xyz(), Color4::rgb(),
Vector4::xy(), Vector3::xy()
*/
template<char ...components, class T> inline constexpr typename Implementation::TypeForSize<sizeof...(components), T>::Type swizzle(const T& vector) {
return {vector[Implementation::GetComponent<T::size, components>::value()]...};
@ -123,7 +124,8 @@ swizzle(const T&), but unless the result is marked with
`constexpr`, the evaluation of the swizzling operation probably won't be
evaluated at compile time, but at runtime.
@see Vector4::xyz(), Vector4::rgb(), Vector4::xy(), Vector3::xy()
@see @ref matrix-vector-component-access, Vector4::xyz(), Color4::rgb(),
Vector4::xy(), Vector3::xy()
*/
template<class T, size_t newSize> inline constexpr typename Implementation::TypeForSize<newSize-1, T>::Type swizzle(const T& vector, const char(&components)[newSize]) {
return Implementation::swizzleFrom(typename Implementation::GenerateSequence<newSize-1>::Type(), vector, components);

Loading…
Cancel
Save