SYNOPSIS
#include <agar/core.h> #include <agar/gui.h> #include <agar/math/m.h>
DESCRIPTION
The
M_Vector and
M_Matrix(3) interfaces implement linear algebra operations on (real or complex valued)
n dimensional vectors, and
m by
n matrices.
Optimized interfaces are provided for fixed-dimensional types (which have
entries directly accessible as
x, y, z and
w). Arbitrary-dimensional types may or may not use fixed arrays in memory.
For example, the "sparse" backend uses a sparse matrix representation,
and the "db" backend stores vector entries in a database.
Backends can be selected at run-time, or Agar-Math can be compiled to provide inline expansions of all operations of a specific backend. Vector extensions (such as SSE and AltiVec) are used by default, if a runtime cpuinfo check determines that they are available (the build remains compatible with non-vector platforms, at the cost of extra function calls). For best performance, Agar should be compiled with "--with-sse=inline", or "--with-altivec=inline".
Backends can be selected at run-time, or Agar-Math can be compiled to provide inline expansions of all operations of a specific backend. Vector extensions (such as SSE and AltiVec) are used by default, if a runtime cpuinfo check determines that they are available (the build remains compatible with non-vector platforms, at the cost of extra function calls). For best performance, Agar should be compiled with "--with-sse=inline", or "--with-altivec=inline".
VECTORS IN RN
The following routines operate on dynamically-allocated vectors in Rn.
Unlike
M_Matrix (which might use different memory representations), vector entries are always
directly accessible through the
v array.
The
M_Vector structure is defined as:
The following backends are currently available for M_Vector:
typedef struct m_vector { Uint m; /* Size */ M_Real *v; /* Elements */ } M_Vector;
The following backends are currently available for M_Vector:
fpu | Native scalar floating point methods. |
VECTORS IN RN: INITIALIZATION
M_Vector * M_VecNew (Uint m)
void M_VecFree (M_Vector *v)
int M_VecResize (M_Vector *v, Uint m)
void M_VecSetZero (M_Vector *v)
M_Vector * M_ReadVector (AG_DataSource *ds)
void M_WriteVector (AG_DataSource *ds, const M_Vector *v)
The M_VecNew() function allocates a new vector in Rn. M_VecFree() releases all resources allocated for the specified vector.
M_VecResize() resizes the vector v to m. Existing entries are preserved, but new entries are left uninitialized. If insufficient memory is available, -1 is returned and an error message is set. On success, the function returns 0.
M_VecSetZero() initializes v to the zero vector.
M_ReadVector() reads a M_Vector from a data source and M_WriteVector() writes vector v to a data source; see AG_DataSource(3) for details.
VECTORS IN RN: ACCESSING ELEMENTS
M_Real * M_VecGetElement (const M_Vector *v, Uint i)
M_Real M_VecGet (const M_Vector *v, Uint i)
M_Vector * M_VecFromReals (Uint n, const M_Real *values)
M_Vector * M_VecFromFloats (Uint n, const float *values)
M_Vector * M_VecFromDoubles (Uint n, const double *values)
M_VecGetElement() returns a direct pointer to entry i in the (non-sparse) vector v. The M_VecGet() function returns the value of entry i in a vector v, which can be a sparse vector.
M_VecFromReals(), M_VecFromFloats(), and M_VecFromDoubles() generate an M_Vector from an array of M_Real, float or double.
VECTORS IN RN: BASIC OPERATIONS
int M_VecCopy (M_Vector *vDst, const M_Vector *vSrc)
M_Vector * M_VecFlip (const M_Vector *v)
M_Vector * M_VecScale (const M_Vector *v, M_Real c)
void M_VecScalev (M_Vector *v, M_Real c)
M_Vector * M_VecAdd (const M_Vector *a, const M_Vector *b)
int M_VecAddv (M_Vector *a, const M_Vector *b)
M_Vector * M_VecSub (const M_Vector *a, const M_Vector *b)
int M_VecSubv (M_Vector *a, const M_Vector *b)
M_Real M_VecLen (const M_Vector *v)
M_Real M_VecDot (const M_Vector *a, const M_Vector *b)
M_Real M_VecDistance (const M_Vector *a, const M_Vector *b)
M_Vector * M_VecNorm (const M_Vector *v)
M_Vector * M_VecLERP (const M_Vector *a, const M_Vector *b, M_Real t)
M_Vector * M_VecElemPow (const M_Vector *v, M_Real pow)
The M_VecCopy() routine copies the contents of vector vSrc into vDst. Both vectors must have the same size.
The M_VecFlip() function returns the vector v scaled to -1.
M_VecScale() scales the vector v by factor c and returns the resulting vector. M_VecScalev() scales the vector in place.
M_VecAdd() returns the sum of a and b, which must be of equal size. The M_VecAddv() variant writes the result back into a.
M_VecSub() returns the difference (a - b). Both vectors must be of equal size. The M_VecSubv() variant writes the result back into a.
M_VecLen() returns the Euclidean length of a vector.
M_VecDot() returns the dot product of vectors a and b.
M_VecDistance() returns the Euclidean distance between a and b.
M_VecNorm() returns the normalized (unit-length) form of v.
M_VecLERP() returns the result of linear interpolation between equally-sized vectors a and b, with scaling factor t.
M_ElemPow() raises the entries of v to the power pow, and returns the resulting vector.
VECTORS IN R2
The following routines operate on vectors in R2, which are always
represented by the structure:
The following backends are currently available for M_Vector2:
typedef struct m_vector2 { M_Real x, y; } M_Vector2;
The following backends are currently available for M_Vector2:
fpu | Native scalar floating point methods. |
VECTORS IN R2: INITIALIZATION
M_Vector2 M_VecI2 (void)
M_Vector2 M_VecJ2 (void)
M_Vector2 M_VecZero2 (void)
M_Vector2 M_VecGet2 (M_Real x, M_Real y)
M_Vector2 M_VECTOR2 (M_Real x, M_Real y)
void M_VecSet2 (M_Vector2 *v, M_Real x, M_Real y)
void M_VecCopy2 (M_Vector2 *vDst, const M_Vector2 *vSrc)
M_Vector2 M_VecFromProj2 (M_Vector3 p)
M_Vector3 M_VecToProj2 (M_Vector2 v, M_Real z)
M_Vector2 M_ReadVector2 (AG_DataSource *ds)
void M_WriteVector2 (AG_DataSource *ds, const M_Vector2 *v)
The M_VecI2() and M_VecJ2() routines return the basis vectors [1;0] and [0;1], respectively. M_VecZero2() returns the zero vector [0;0]. M_VecGet2() returns the vector [x,y]. The M_VECTOR2() macro expands to a static initializer for the vector [x,y].
M_VecSet2() writes the values [x,y] into vector v (note that entries are also directly accessible via the M_Vector2 structure).
M_VecFromProj2() returns an Euclidean vector corresponding to p in projective space. If p is at infinity, a fatal divide-by-zero condition is raised. M_VecToProj2() returns the vector in projective space corresponding to v in Euclidean space (if w=1), or v at infinity (if w=0).
M_ReadVector2() reads a M_Vector2 from a data source and M_WriteVector2() writes vector v to a data source; see AG_DataSource(3) for details.
VECTORS IN R2: BASIC OPERATIONS
int M_VecCopy2 (M_Vector2 *vDst, const M_Vector2 *vSrc)
M_Vector2 M_VecFlip2 (M_Vector2 v)
M_Real M_VecLen2 (M_Vector2 v)
M_Real M_VecLen2p (const M_Vector2 *v)
M_Real M_VecDot2 (M_Vector2 a, M_Vector2 b)
M_Real M_VecDot2p (const M_Vector2 *a, const M_Vector2 *b)
M_Real M_VecPerpDot2 (M_Vector2 a, M_Vector2 b)
M_Real M_VecPerpDot2p (const M_Vector2 *a, const M_Vector2 *b)
M_Real M_VecDistance2 (M_Vector2 a, M_Vector2 b)
M_Real M_VecDistance2p (const M_Vector2 *a, const M_Vector2 *b)
M_Vector2 M_VecNorm2 (M_Vector2 v)
M_Vector2 M_VecNorm2p (const M_Vector2 *v)
void M_VecNorm2v (M_Vector2 *v)
M_Vector2 M_VecScale2 (M_Vector2 v, M_Real c)
M_Vector2 M_VecScale2p (const M_Vector2 *v, M_Real c)
void M_VecScale2v (M_Vector2 *v, M_Real c)
M_Vector2 M_VecAdd2 (M_Vector2 a, M_Vector2 b)
M_Vector2 M_VecAdd2p (const M_Vector2 *a, const M_Vector2 *b)
void M_VecAdd2v (M_Vector2 *a, const M_Vector2 *b)
M_Vector2 M_VecSum2 (const M_Vector2 *vs, Uint count)
M_Vector2 M_VecSub2 (M_Vector2 a, M_Vector2 b)
M_Vector2 M_VecSub2p (const M_Vector2 *a, const M_Vector2 *b)
void M_VecSub2v (M_Vector2 *a, const M_Vector2 *b)
M_Vector2 M_VecAvg2 (M_Vector2 a, M_Vector2 b)
M_Vector2 M_VecAvg2p (const M_Vector2 *a, const M_Vector2 *b)
M_Vector2 M_VecLERP2 (M_Vector2 a, M_Vector2 b, M_Real t)
M_Vector2 M_VecLERP2p (M_Vector2 *a, M_Vector2 *b, M_Real t)
M_Vector2 M_VecElemPow2 (M_Vector2 *v, M_Real pow)
M_Real M_VecVecAngle2 (M_Vector2 a, M_Vector2 b)
The M_VecCopy2() function copies the contents of vector vSrc into vDst.
The function M_VecFlip2() returns the vector scaled to -1.
M_VecLen2() and M_VecLen2p() return the real length of vector v, that is Sqrt(x^2 + y^2).
M_VecDot2() and M_VecDot2p() return the dot product of vectors a and b, that is (a.x*b.x + a.y*b.y).
M_VecPerpDot2() and M_VecPerpDot2p() compute the "perp dot product" of a and b, which is (a.x*b.y - a.y*b.x).
M_VecDistance2() and M_VecDistance2p() return the real distance between vectors a and b, that is the length of the difference vector (a - b).
M_VecNorm2() and M_VecNorm2p() return the normalized (unit-length) form of v. The M_VecNorm2v() variant normalizes the vector in-place.
M_VecScale2() and M_VecScale2p() multiplies vector v by scalar c and returns the result. The M_VecScale2v() variant scales the vector in-place.
M_VecAdd2() and M_VecAdd2p() return the sum of vectors a and b. The M_VecAdd2v() variant returns the result back into a. The M_VecSum2() function returns the vector sum of the count vectors in the vs array.
M_VecSub2() and M_VecSub2p() return the difference of vectors (a-b). The M_VecSub2v() variant returns the result back into a.
The M_VecAvg2() and M_VecAvg2p() routines compute the average of two vectors (a+b)/2.
The functions M_VecLERP2() and M_VecLERP2p() interpolate linearly between vectors a and b, using the scaling factor t and returns the result. The result is computed as a+(b-a)*t.
M_VecElemPow2() raises the entries of v to the power pow, and returns the resulting vector.
M_VecVecAngle2() returns the angle (in radians) between vectors a and b, about the origin.
VECTORS IN R3
The following routines operate on vectors in R3, which are represented
by the structure:
Notice that SIMD extensions force single-precision floats, regardless of the precision for which Agar-Math was built (if a 3-dimensional vector of higher precision is required, the general M_Vector type may be used).
The following backends are currently available for M_Vector3:
#ifdef HAVE_SSE typedef union m_vector3 { __m128 m128; struct { float x, y, z, _pad; }; } M_Vector3; #else typedef struct m_vector3 { M_Real x, y, z; } M_Vector3; #endif
Notice that SIMD extensions force single-precision floats, regardless of the precision for which Agar-Math was built (if a 3-dimensional vector of higher precision is required, the general M_Vector type may be used).
The following backends are currently available for M_Vector3:
fpu | Native scalar floating point methods. |
sse | Accelerate operations using Streaming SIMD Extensions (SSE). |
sse3 | Accelerate operations using SSE3 extensions. |
VECTORS IN R3: INITIALIZATION
M_Vector3 M_VecI3 (void)
M_Vector3 M_VecJ3 (void)
M_Vector3 M_VecK3 (void)
M_Vector3 M_VecZero3 (void)
M_Vector3 M_VecGet3 (M_Real x, M_Real y, M_Real z)
M_Vector3 M_VECTOR3 (M_Real x, M_Real y, M_Real z)
void M_VecSet3 (M_Vector3 *v, M_Real x, M_Real y, M_Real z)
void M_VecCopy3 (M_Vector3 *vDst, const M_Vector3 *vSrc)
M_Vector3 M_VecFromProj3 (M_Vector4 p)
M_Vector4 M_VecToProj3 (M_Vector3 v, M_Real w)
M_Vector3 M_ReadVector3 (AG_DataSource *ds)
void M_WriteVector3 (AG_DataSource *ds, const M_Vector3 *v)
The M_VecI3(), M_VecJ3() and M_VecK3() routines return the basis vectors [1;0;0], [0;1;0] and [0;0;1], respectively. M_VecZero3() returns the zero vector [0;0;0]. M_VecGet3() returns the vector [x,y,z]. The M_VECTOR3() macro expands to a static initializer for the vector [x,y,z].
M_VecSet3() writes the values [x,y,z] into vector v (note that entries are also directly accessible via the M_Vector3 structure).
M_VecFromProj3() returns an Euclidean vector corresponding to the specified vector p in projective space. If p is at infinity, a fatal divide-by-zero condition is raised.
M_ReadVector3() reads a M_Vector3 from a data source and M_WriteVector3() writes vector v to a data source; see AG_DataSource(3) for details.
VECTORS IN R3: BASIC OPERATIONS
int M_VecCopy3 (M_Vector3 *vDst, const M_Vector3 *vSrc)
M_Vector3 M_VecFlip3 (M_Vector3 v)
M_Real M_VecLen3 (M_Vector3 v)
M_Real M_VecLen3p (const M_Vector3 *v)
M_Real M_VecDot3 (M_Vector3 a, M_Vector3 b)
M_Real M_VecDot3p (const M_Vector3 *a, const M_Vector3 *b)
M_Real M_VecDistance3 (M_Vector3 a, M_Vector3 b)
M_Real M_VecDistance3p (const M_Vector3 *a, const M_Vector3 *b)
M_Vector3 M_VecNorm3 (M_Vector3 v)
M_Vector3 M_VecNorm3p (const M_Vector3 *v)
void M_VecNorm3v (M_Vector3 *v)
M_Vector3 M_VecCross3 (M_Vector3 a, M_Vector3 b)
M_Vector3 M_VecCross3p (const M_Vector3 *a, const M_Vector3 *b)
M_Vector3 M_VecNormCross3 (M_Vector3 a, M_Vector3 b)
M_Vector3 M_VecNormCross3p (const M_Vector3 *a, const M_Vector3 *b)
M_Vector3 M_VecScale3 (M_Vector3 v, M_Real c)
M_Vector3 M_VecScale3p (const M_Vector3 *v, M_Real c)
void M_VecScale3v (M_Vector3 *v, M_Real c)
M_Vector3 M_VecAdd3 (M_Vector3 a, M_Vector3 b)
M_Vector3 M_VecAdd3p (const M_Vector3 *a, const M_Vector3 *b)
void M_VecAdd3v (M_Vector3 *a, const M_Vector3 *b)
M_Vector3 M_VecSum3 (const M_Vector3 *vs, Uint count)
M_Vector3 M_VecSub3 (M_Vector3 a, M_Vector3 b)
M_Vector3 M_VecSub3p (const M_Vector3 *a, const M_Vector3 *b)
void M_VecSub3v (M_Vector3 *a, const M_Vector3 *b)
M_Vector3 M_VecAvg3 (M_Vector3 a, M_Vector3 b)
M_Vector3 M_VecAvg3p (const M_Vector3 *a, const M_Vector3 *b)
M_Vector3 M_VecLERP3 (M_Vector3 a, M_Vector3 b, M_Real t)
M_Vector3 M_VecLERP3p (M_Vector3 *a, M_Vector3 *b, M_Real t)
M_Vector3 M_VecElemPow3 (M_Vector3 *v, M_Real pow)
void M_VecVecAngle3 (M_Vector3 a, M_Vector3 b, M_Real *theta, M_Real *phi)
The M_VecCopy3() function copies the contents of vector vSrc into vDst.
The function M_VecFlip3() returns the vector scaled to -1.
M_VecLen3() and M_VecLen3p() return the real length of vector v, that is Sqrt(x^2 + y^2 + z^2).
M_VecDot3() and M_VecDot3p() return the dot product of vectors a and b, that is (a.x*b.x + a.y*b.y + a.z*b.z).
M_VecDistance3() and M_VecDistance3p() return the real distance between vectors a and b, that is the length of the difference vector (a - b).
M_VecNorm3() and M_VecNorm3p() return the normalized (unit-length) form of v. The M_VecNorm3v() variant normalizes the vector in-place.
M_VecCross3() and M_VecCross3p() return the cross-product (also known as the "vector product" or "Gibbs vector product) of vectors a and b.
M_VecNormCross3() and M_VecNormCross3() return the normalized cross-product of vectors a and b. This is a useful operation in computer graphics (e.g., for computing plane normals from the vertices of a triangle).
M_VecScale3() and M_VecScale3p() multiplies vector v by scalar c and returns the result. The M_VecScale3v() variant scales the vector in-place.
M_VecAdd3() and M_VecAdd3p() return the sum of vectors a and b. The M_VecAdd3v() variant returns the result back into a. The M_VecSum3() function returns the vector sum of the count vectors in the vs array.
M_VecSub3() and M_VecSub3p() return the difference of vectors (a-b). The M_VecSub3v() variant returns the result back into a.
The M_VecAvg3() and M_VecAvg3p() routines compute the average of two vectors (a+b)/2.
The functions M_VecLERP3() and M_VecLERP3p() interpolate linearly between vectors a and b, using the scaling factor t and returns the result. The result is computed as a+(b-a)*t.
M_VecElemPow3() raises the entries of v to the power pow, and returns the resulting vector.
M_VecVecAngle3() returns the two angles (in radians) between vectors a and b, about the origin.
VECTORS IN R4
The following routines operate on vectors in R4, which are represented
by the structure:
Notice that SIMD extensions force single-precision floats, regardless of the precision for which Agar-Math was built (if a 4-dimensional vector of higher precision is required, the general M_Vector type may be used).
The following backends are currently available for M_Vector4:
#ifdef HAVE_SSE typedef union m_vector4 { __m128 m128; struct { float x, y, z, w; }; } M_Vector4; #else typedef struct m_vector4 { M_Real x, y, z, w; } M_Vector4; #endif
Notice that SIMD extensions force single-precision floats, regardless of the precision for which Agar-Math was built (if a 4-dimensional vector of higher precision is required, the general M_Vector type may be used).
The following backends are currently available for M_Vector4:
fpu | Native scalar floating point methods. |
sse | Accelerate operations using Streaming SIMD Extensions (SSE). |
sse3 | Accelerate operations using SSE3 extensions. |
VECTORS IN R4: INITIALIZATION
M_Vector4 M_VecI4 (void)
M_Vector4 M_VecJ4 (void)
M_Vector4 M_VecK4 (void)
M_Vector4 M_VecL4 (void)
M_Vector4 M_VecZero4 (void)
M_Vector4 M_VecGet4 (M_Real x, M_Real y, M_Real z, M_Real w)
M_Vector4 M_VECTOR4 (M_Real x, M_Real y, M_Real z, M_Real w)
void M_VecSet4 (M_Vector4 *v, M_Real x, M_Real y, M_Real z, M_Real w)
void M_VecCopy4 (M_Vector4 *vDst, const M_Vector4 *vSrc)
M_Vector4 M_ReadVector4 (AG_DataSource *ds)
void M_WriteVector4 (AG_DataSource *ds, const M_Vector4 *v)
The M_VecI4(), M_VecJ4(), M_VecK4() and M_VecL4() routines return the basis vectors [1;0;0;0], [0;1;0;0], [0;0;1;0] and [0;0;0;1], respectively. M_VecZero4() returns the zero vector [0;0;0;0]. M_VecGet4() returns the vector [x,y,z,w]. The M_VECTOR4() macro expands to a static initializer for the vector [x,y,z,w].
M_VecSet4() writes the values [x,y,z,w] into vector v (note that entries are also directly accessible via the M_Vector4 structure).
M_ReadVector4() reads a M_Vector4 from a data source and M_WriteVector4() writes vector v to a data source; see AG_DataSource(4) for details.
VECTORS IN R4: BASIC OPERATIONS
int M_VecCopy4 (M_Vector4 *vDst, const M_Vector4 *vSrc)
M_Vector4 M_VecFlip4 (M_Vector4 v)
M_Real M_VecLen4 (M_Vector4 v)
M_Real M_VecLen4p (const M_Vector4 *v)
M_Real M_VecDot4 (M_Vector4 a, M_Vector4 b)
M_Real M_VecDot4p (const M_Vector4 *a, const M_Vector4 *b)
M_Real M_VecDistance4 (M_Vector4 a, M_Vector4 b)
M_Real M_VecDistance4p (const M_Vector4 *a, const M_Vector4 *b)
M_Vector4 M_VecNorm4 (M_Vector4 v)
M_Vector4 M_VecNorm4p (const M_Vector4 *v)
void M_VecNorm4v (M_Vector4 *v)
M_Vector4 M_VecScale4 (M_Vector4 v, M_Real c)
M_Vector4 M_VecScale4p (const M_Vector4 *v, M_Real c)
void M_VecScale4v (M_Vector4 *v, M_Real c)
M_Vector4 M_VecAdd4 (M_Vector4 a, M_Vector4 b)
M_Vector4 M_VecAdd4p (const M_Vector4 *a, const M_Vector4 *b)
void M_VecAdd4v (M_Vector4 *a, const M_Vector4 *b)
M_Vector4 M_VecSum4 (const M_Vector4 *vs, Uint count)
M_Vector4 M_VecSub4 (M_Vector4 a, M_Vector4 b)
M_Vector4 M_VecSub4p (const M_Vector4 *a, const M_Vector4 *b)
void M_VecSub4v (M_Vector4 *a, const M_Vector4 *b)
M_Vector4 M_VecAvg4 (M_Vector4 a, M_Vector4 b)
M_Vector4 M_VecAvg4p (const M_Vector4 *a, const M_Vector4 *b)
M_Vector4 M_VecLERP4 (M_Vector4 a, M_Vector4 b, M_Real t)
M_Vector4 M_VecLERP4p (M_Vector4 *a, M_Vector4 *b, M_Real t)
M_Vector4 M_VecElemPow4 (M_Vector4 *v, M_Real pow)
void M_VecVecAngle4 (M_Vector4 a, M_Vector4 b, M_Real *phi1, M_Real *phi2, M_Real *phi3)
The M_VecCopy4() function copies the contents of vector vSrc into vDst.
The function M_VecFlip4() returns the vector scaled to -1.
M_VecLen4() and M_VecLen4p() return the real length of vector v, that is Sqrt(x^2 + y^2 + z^2 + w^2).
M_VecDot4() and M_VecDot4p() return the dot product of vectors a and b, that is (a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w).
M_VecDistance4() and M_VecDistance4p() return the real distance between vectors a and b, that is the length of the difference vector (a - b).
M_VecNorm4() and M_VecNorm4p() return the normalized (unit-length) form of v. The M_VecNorm4v() variant normalizes the vector in-place.
M_VecScale4() and M_VecScale4p() multiplies vector v by scalar c and returns the result. The M_VecScale4v() variant scales the vector in-place.
M_VecAdd4() and M_VecAdd4p() return the sum of vectors a and b. The M_VecAdd4v() variant returns the result back into a. The M_VecSum4() function returns the vector sum of the count vectors in the vs array.
M_VecSub4() and M_VecSub4p() return the difference of vectors (a-b). The M_VecSub4v() variant returns the result back into a.
The M_VecAvg4() and M_VecAvg4p() routines compute the average of two vectors (a+b)/2.
The functions M_VecLERP4() and M_VecLERP4p() interpolate linearly between vectors a and b, using the scaling factor t and returns the result. The result is computed as a+(b-a)*t.
M_VecElemPow4() raises the entries of v to the power pow, and returns the resulting vector.
M_VecVecAngle4() returns the three angles (in radians) between vectors a and b, about the origin.
SEE ALSO
HISTORY
The
M_Vector interface first appeared in
Agar 1.3.4.