Vectors consist of a set of elements (usually floating point or integer scalars) that are regularly used to describe a point in space or a direction. For more information see this description of Euclidiean Vectors.
The [MathFu][] [Vector][] class is a template declared in [mathfu/vector.h](@ref mathfu/vector.h) which has been specialized and optimized for regularly used cases. Implementing [Vector][] as a template reduces code duplication, provides compile time optimization opportunities through specialization and allows users to use the class with any scalar type.
[Vector][] template takes two arguments: the type and number of elements in the [Vector][].
For example, a 2-dimensional floating point vector variable is declared using the following:
mathfu::Vector<float, 2> vector;
To eliminate the need for explicit template instantiation, [GLSL][] style typedef
s are provided in [mathfu/glsl_mappings.h](@ref mathfu/glsl_mappings.h). Using a [GLSL][] style typedef
a 2-dimensional floating point vector variable is declared using the following:
math::vec2 vector;
For efficiency, [Vector][] is uninitialized when constructed. Constructors are provided for common vector sizes that allow initialization on construction:
mathfu::vec2 vector(1.0f, 2.0f);
It's also possible to initialize a [Vector][] with another instance:
mathfu::vec2 vector1(1.0f, 2.0f); mathfu::vec2 vector2(vector1);
This can also be achieved with:
mathfu::vec2 vector1(1.0f, 2.0f); mathfu::vec2 vector2 = vector1;
[Vector][] provides array and [GLSL][] style accessors. For example, to read two elements from a 2-dimensional vector using array accessors:
const mathfu::vec2 vector(1.0f, 2.0f); float x = vector[0]; float y = vector[1];
It's also possible to read elements from 2, 3 and 4-dimensional vectors using [GLSL][] style accessors:
const mathfu::vec4 vector(1.0f, 2.0f, 3.0f, 4.0f); float x = vector.x(); float y = vector.y(); float z = vector.z(); float w = vector.w();
Similar to [GLSL][], [Vector][] provides accessors which allow a subset of elements to be accessed:
const mathfu::vec3 vector1(1.0f, 2.0f, 3.0f); mathfu::vec3 xy = vector1.xy();
Individual elements returned by [Vector][]'s array accessors are references that can be assigned values to update the contents of the class:
mathfu::vec2 vector(1.0f, 2.0f); vector[0] = 3.0f; vector[1] = 4.0f;
[Vector][] supports in-place and out-of-place arithmetic operators (addition, subtraction, multiplication, division) that perform component-wise operations.
For example, two vectors can be added together using the following:
const mathfu::vec2 vector1(1.0f, 2.0f), vector2(3.0f, 4.0f); mathfu::vec2 vector3 = vector1 + vector2;
The above results in the values (4.0f, 6.0f)
stored in vector3
while preserving the values of vector1
and vector2
.
The same can be achieved with an in-place addition which mutates vector1
:
mathfu::vec2 vector1(1.0f, 2.0f); const mathfu::vec2 vector2(3.0f, 4.0f); vector1 += vector2;
Subtraction is similar to addition:
const mathfu::vec2 vector1(4.0f, 6.0f), vector2(3.0f, 4.0f); mathfu::vec2 vector3 = vector2 - vector1;
Multiplication is performed component-wise, which means that each component is multiplied with the same index component in the other [Vector][] involved in the operation:
const mathfu::vec2 vector1(2.0f, 0.5f), vector2(3.0f, 10.0f); vector3 = vector1 * vector2;
The above results in the values (6.0f, 5.0f)
stored in vector3
while preserving the values of vector1
and vector2
.
Similar to the other operators, multiplication can be performed in place:
mathfu::vec2 vector1(2.0f, 0.5f); const mathfu::vec2 vector2(3.0f, 10.0f); vector1 *= vector2;
Division is also a component-wise operation:
const mathfu::vec2 vector1(4.0f, 4.0f), vector2(2.0f, 4.0f); vector3 = vector1 / vector2;
The above results in the values (2.0f, 1.0f)
stored in vector3
while preserving the values of vector1
and vector2
.
Commonly used constants are provided by [mathfu/constants.h](@ref mathfu/constants.h). These values eliminate the need to construct [Vector][] objects for common values like cardinal axes.
For example, the following initializes a 2-dimensional vector with the X-axis:
const mathfu::vec2 vector = mathfu::kAxisX2f;
[Vector][] also provides functions for commonly used geometric operations that are utilized by graphics and games developers.
For example, the length of a [Vector][] is calculated using [Length()](@ref mathfu::Vector::Length):
const mathfu::vec2 vector(3.0f, 4.0f); float length = vector.Length();
The projection of one [Vector][] onto another (dot product) can be calculated using [DotProduct()](@ref mathfu::Vector::DotProduct). For example, the following calculates the projection of a vector onto the X-axis:
float projection = mathfu::vec2::DotProduct(mathfu::vec2(5.0f, 2.0f), mathfu::kAxisX2f);
It's possible to normalize (scale to a length of 1) a vector in-place using [Normalize()](@ref mathfu::Vector::Normalize) or out-of-place using [Normalized()](@ref mathfu::Vector::Normalized). For example, the following normalizes the vector in-place:
mathfu::vec2 vector(3.0f, 4.0f); vector.Normalize();
The cross product of two 3-dimensional [Vectors][] (the vector perpendicular to two vectors) can be calculated using [CrossProduct()](@ref mathfu::Vector::CrossProduct), for example:
mathfu::vec3 zaxis = mathfu::vec3::CrossProduct(mathfu::kAxisX3f, mathfu::kAxisY3f);
Alternatively, to create three points and compute the normal of the plane defined by the points use:
mathfu::vec3 point1(0.5f, 0.4f, 0.1f); mathfu::vec3 point2(0.4f, 0.9f, 0.1f); mathfu::vec3 point3(0.1f, 0.8f, 0.6f); mathfu::vec3 vector1 = point2 - point1; mathfu::vec3 vector2 = point3 - point1; mathfu::vec3 normal = Vector<float, 3>::CrossProduct(vector2, vector1);
In addition, to basic arithmetic and geometric operations, [Vector][] also implements functions to perform the following:
The size of the class can change based upon the [Build Configuration][] so it should not be treated like a C style array. To serialize the class to a flat array see [VectorPacked](@ref mathfu::VectorPacked).
For example, to pack (store) an unpacked to packed vector:
mathfu::vec3 vector(3.0f, 2.0f, 1.0f); mathfu::vec3_packed packed = vector;
Since [VectorPacked][] is plain-old-data (POD) it can be cast to an array of elements of the same type used by the [Vector][] so it's possible to use an array of [VectorPacked][] data structures to contiguous arrays of data like vertex buffers.
Similarly, [VectorPacked][] can be used to deserialize (load) data into [Vector][]:
VectorPacked<float, 3> packed = { 3, 2, 1 }; Vector<float, 3> vector(packed);
[Build Configuration]: @ref mathfu_build_config [MathFu]: @ref mathfu_overview [GLSL]: http://www.opengl.org/documentation/glsl/ [Vector]: @ref mathfu::Vector [VectorPacked]: @ref mathfu::VectorPacked